modest-ui-actions.c: some alignment in the code
[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 (
1352                                 MODEST_MAIN_WINDOW(window),
1353                                 MODEST_WIDGET_TYPE_HEADER_VIEW);
1354                 if (!header_view)
1355                         return;
1356         
1357                 modest_header_view_select_next (
1358                                 MODEST_HEADER_VIEW(header_view)); 
1359         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1360                 modest_msg_view_window_select_next_message (
1361                                 MODEST_MSG_VIEW_WINDOW (window));
1362         } else {
1363                 g_return_if_reached ();
1364         }
1365 }
1366
1367 void 
1368 modest_ui_actions_on_prev (GtkAction *action, 
1369                            ModestWindow *window)
1370 {
1371         g_return_if_fail (MODEST_IS_WINDOW(window));
1372
1373         if (MODEST_IS_MAIN_WINDOW (window)) {
1374                 GtkWidget *header_view;
1375                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1376                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
1377                 if (!header_view)
1378                         return;
1379                 
1380                 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view)); 
1381         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1382                 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1383         } else {
1384                 g_return_if_reached ();
1385         }
1386 }
1387
1388 void 
1389 modest_ui_actions_on_sort (GtkAction *action, 
1390                            ModestWindow *window)
1391 {
1392         g_return_if_fail (MODEST_IS_WINDOW(window));
1393
1394         if (MODEST_IS_MAIN_WINDOW (window)) {
1395                 GtkWidget *header_view;
1396                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1397                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
1398                 if (!header_view) {
1399                         modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1400
1401                         return;
1402                 }
1403
1404                 /* Show sorting dialog */
1405                 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);     
1406         }
1407 }
1408
1409 static void
1410 new_messages_arrived (ModestMailOperation *self, 
1411                       gint new_messages,
1412                       gpointer user_data)
1413 {
1414         if (new_messages == 0)
1415                 return;
1416
1417         modest_platform_on_new_msg ();
1418 }
1419
1420 /*
1421  * This function performs the send & receive required actions. The
1422  * window is used to create the mail operation. Typically it should
1423  * always be the main window, but we pass it as argument in order to
1424  * be more flexible.
1425  */
1426 void
1427 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1428 {
1429         gchar *acc_name = NULL;
1430         ModestMailOperation *mail_op;
1431
1432         /* If no account name was provided then get the current account, and if
1433            there is no current account then pick the default one: */
1434         if (!account_name) {
1435                 acc_name = g_strdup (modest_window_get_active_account(win));
1436                 if (!acc_name)
1437                         acc_name  = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1438                 if (!acc_name) {
1439                         g_printerr ("modest: cannot get default account\n");
1440                         return;
1441                 }
1442         } else {
1443                 acc_name = g_strdup (account_name);
1444         }
1445
1446         /* Set send/receive operation in progress */    
1447         modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1448
1449         mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1450                                                                  G_OBJECT (win),
1451                                                                  modest_ui_actions_send_receive_error_handler,
1452                                                                  NULL);
1453
1454         g_signal_connect (G_OBJECT(mail_op), "progress-changed", 
1455                           G_CALLBACK (_on_send_receive_progress_changed), 
1456                           win);
1457
1458         /* Send & receive. */
1459         /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1460         /* Receive and then send. The operation is tagged initially as
1461            a receive operation because the account update performs a
1462            receive and then a send. The operation changes its type
1463            internally, so the progress objects will receive the proper
1464            progress information */
1465         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1466         modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1467         g_object_unref (G_OBJECT (mail_op));
1468         
1469         /* Free */
1470         g_free (acc_name);
1471 }
1472
1473
1474 static void
1475 modest_ui_actions_do_cancel_send (const gchar *account_name,  
1476                                   ModestWindow *win)
1477 {
1478         TnyTransportAccount *transport_account;
1479         TnySendQueue *send_queue = NULL;
1480         GError *error = NULL;
1481
1482         /* Get transport account */
1483         transport_account =
1484                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1485                                       (modest_runtime_get_account_store(),
1486                                        account_name,
1487                                        TNY_ACCOUNT_TYPE_TRANSPORT));
1488         if (!transport_account) {
1489                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1490                 goto frees;
1491         }
1492
1493         /* Get send queue*/
1494         send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1495         if (!TNY_IS_SEND_QUEUE(send_queue)) {
1496                 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1497                              MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1498                              "modest: could not find send queue for account\n");
1499         } else {
1500                 /* Keeep messages in outbox folder */
1501                 tny_send_queue_cancel (send_queue, FALSE, &error);
1502         }       
1503
1504  frees:
1505         if (transport_account != NULL) 
1506                 g_object_unref (G_OBJECT (transport_account));
1507 }
1508
1509 static void
1510 modest_ui_actions_cancel_send_all (ModestWindow *win) 
1511 {
1512         GSList *account_names, *iter;
1513
1514         account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), 
1515                                                           TRUE);
1516
1517         iter = account_names;
1518         while (iter) {                  
1519                 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1520                 iter = g_slist_next (iter);
1521         }
1522
1523         modest_account_mgr_free_account_names (account_names);
1524         account_names = NULL;
1525 }
1526
1527 void
1528 modest_ui_actions_cancel_send (GtkAction *action,  ModestWindow *win)
1529
1530 {
1531         /* Check if accounts exist */
1532         gboolean accounts_exist = 
1533                 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1534         
1535         /* If not, allow the user to create an account before trying to send/receive. */
1536         if (!accounts_exist)
1537                 modest_ui_actions_on_accounts (NULL, win);
1538         
1539         /* Cancel all sending operaitons */     
1540         modest_ui_actions_cancel_send_all (win);
1541 }
1542
1543 /*
1544  * Refreshes all accounts. This function will be used by automatic
1545  * updates
1546  */
1547 void
1548 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1549 {
1550         GSList *account_names, *iter;
1551
1552         account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), 
1553                                                           TRUE);
1554
1555         iter = account_names;
1556         while (iter) {                  
1557                 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1558                 iter = g_slist_next (iter);
1559         }
1560
1561         modest_account_mgr_free_account_names (account_names);
1562         account_names = NULL;
1563 }
1564
1565 void 
1566 modest_do_refresh_current_folder(ModestWindow *win)
1567 {
1568         /* Refresh currently selected folder. Note that if we only
1569            want to retreive the headers, then the refresh only will
1570            invoke a poke_status over all folders, i.e., only the
1571            total/unread count will be updated */
1572         if (MODEST_IS_MAIN_WINDOW (win)) {
1573                 GtkWidget *header_view, *folder_view;
1574                 TnyFolderStore *folder_store;
1575
1576                 /* Get folder and header view */
1577                 folder_view = 
1578                         modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win), 
1579                                                              MODEST_WIDGET_TYPE_FOLDER_VIEW);
1580
1581                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1582
1583                 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1584                         header_view = 
1585                                 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1586                                                                      MODEST_WIDGET_TYPE_HEADER_VIEW);
1587                 
1588                         /* We do not need to set the contents style
1589                            because it hasn't changed. We also do not
1590                            need to save the widget status. Just force
1591                            a refresh */
1592                         modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1593                                                        TNY_FOLDER (folder_store),
1594                                                        folder_refreshed_cb,
1595                                                        MODEST_MAIN_WINDOW (win));
1596                 }
1597                 
1598                 if (folder_store)
1599                         g_object_unref (folder_store);
1600         }
1601 }
1602
1603
1604 /*
1605  * Handler of the click on Send&Receive button in the main toolbar
1606  */
1607 void
1608 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1609 {
1610         /* Check if accounts exist */
1611         gboolean accounts_exist = 
1612                 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1613         
1614         /* If not, allow the user to create an account before trying to send/receive. */
1615         if (!accounts_exist)
1616                 modest_ui_actions_on_accounts (NULL, win);
1617
1618         modest_do_refresh_current_folder (win);
1619         
1620         /* Refresh the active account */
1621         modest_ui_actions_do_send_receive (NULL, win);
1622 }
1623
1624
1625 void
1626 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1627 {
1628         ModestConf *conf;
1629         GtkWidget *header_view;
1630         
1631         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1632
1633         header_view = modest_main_window_get_child_widget (main_window,
1634                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
1635         if (!header_view)
1636                 return;
1637
1638         conf = modest_runtime_get_conf ();
1639         
1640         /* what is saved/restored is depending on the style; thus; we save with
1641          * old style, then update the style, and restore for this new style
1642          */
1643         modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1644         
1645         if (modest_header_view_get_style
1646             (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1647                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1648                                               MODEST_HEADER_VIEW_STYLE_TWOLINES);
1649         else
1650                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1651                                               MODEST_HEADER_VIEW_STYLE_DETAILS);
1652
1653         modest_widget_memory_restore (conf, G_OBJECT(header_view),
1654                                       MODEST_CONF_HEADER_VIEW_KEY);
1655 }
1656
1657
1658 void 
1659 modest_ui_actions_on_header_selected (ModestHeaderView *header_view, 
1660                                       TnyHeader *header,
1661                                       ModestMainWindow *main_window)
1662 {
1663         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1664         g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1665         
1666         /* in the case the folder is empty, show the empty folder message and focus
1667          * folder view */
1668         if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1669                 if (modest_header_view_is_empty (header_view)) {
1670                         TnyFolder *folder = modest_header_view_get_folder (header_view);
1671                         GtkWidget *folder_view = 
1672                                 modest_main_window_get_child_widget (main_window,
1673                                                                      MODEST_WIDGET_TYPE_FOLDER_VIEW);
1674                         if (folder != NULL) 
1675                                 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1676                         gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1677                         return;
1678                 }
1679         }
1680         /* If no header has been selected then exit */
1681         if (!header)
1682                 return;
1683
1684         /* Update focus */
1685         if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1686             gtk_widget_grab_focus (GTK_WIDGET(header_view));
1687
1688         /* Update Main window title */
1689         if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1690                 const gchar *subject = tny_header_get_subject (header);
1691                 if (subject && strlen(subject) > 0)
1692                         gtk_window_set_title (GTK_WINDOW (main_window), subject);
1693                 else
1694                         gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1695         }
1696
1697         /* Update toolbar dimming state */
1698         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1699 }
1700
1701 void
1702 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1703                                        TnyHeader *header,
1704                                        ModestMainWindow *main_window)
1705 {
1706         TnyList *headers;
1707
1708         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1709         
1710         if (!header)
1711                 return;
1712
1713         headers = tny_simple_list_new ();
1714         tny_list_prepend (headers, G_OBJECT (header));
1715
1716         _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1717
1718         g_object_unref (headers);
1719 }
1720
1721 static void
1722 set_active_account_from_tny_account (TnyAccount *account,
1723                                      ModestWindow *window)
1724 {
1725         const gchar *server_acc_name = tny_account_get_id (account);
1726         
1727         /* We need the TnyAccount provided by the
1728            account store because that is the one that
1729            knows the name of the Modest account */
1730         TnyAccount *modest_server_account = modest_server_account = 
1731                 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1732                                                              MODEST_TNY_ACCOUNT_STORE_QUERY_ID, 
1733                                                              server_acc_name);
1734         
1735         const gchar *modest_acc_name = 
1736                 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1737         modest_window_set_active_account (window, modest_acc_name);
1738         g_object_unref (modest_server_account);
1739 }
1740
1741
1742 static void
1743 folder_refreshed_cb (ModestMailOperation *mail_op, 
1744                      TnyFolder *folder, 
1745                      gpointer user_data)
1746 {
1747         ModestMainWindow *win = NULL;
1748         GtkWidget *header_view;
1749         TnyFolder *current_folder;
1750
1751         g_return_if_fail (TNY_IS_FOLDER (folder));
1752
1753         win = MODEST_MAIN_WINDOW (user_data);
1754         header_view = 
1755                 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1756
1757         if (header_view) {
1758                 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1759                 if (current_folder != NULL && folder != current_folder) {
1760                         return;
1761                 }
1762         }
1763
1764         /* Check if folder is empty and set headers view contents style */
1765         if (tny_folder_get_all_count (folder) == 0) {
1766         printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1767                 modest_main_window_set_contents_style (win,
1768                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1769         } else {
1770                 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1771         }
1772 }
1773
1774 void 
1775 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1776                                                TnyFolderStore *folder_store, 
1777                                                gboolean selected,
1778                                                ModestMainWindow *main_window)
1779 {
1780         ModestConf *conf;
1781         GtkWidget *header_view;
1782
1783         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1784
1785         header_view = modest_main_window_get_child_widget(main_window,
1786                                                           MODEST_WIDGET_TYPE_HEADER_VIEW);
1787         if (!header_view)
1788                 return;
1789         
1790         conf = modest_runtime_get_conf ();
1791
1792         if (TNY_IS_ACCOUNT (folder_store)) {
1793                 if (selected) {
1794                         /* Update active account */
1795                         set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1796                         /* Show account details */
1797                         modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1798                 }
1799         } else {
1800                 if (TNY_IS_FOLDER (folder_store) && selected) {
1801                         
1802                         /* Update the active account */
1803                         TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1804                         if (account) {
1805                                 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1806                                 g_object_unref (account);
1807                                 account = NULL;
1808                         }
1809
1810                         /* Set the header style by default, it could
1811                            be changed later by the refresh callback to
1812                            empty */
1813                         modest_main_window_set_contents_style (main_window, 
1814                                                                MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1815
1816                         /* Set folder on header view. This function
1817                            will call tny_folder_refresh_async so we
1818                            pass a callback that will be called when
1819                            finished. We use that callback to set the
1820                            empty view if there are no messages */
1821                         modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1822                                                        TNY_FOLDER (folder_store),
1823                                                        folder_refreshed_cb,
1824                                                        main_window);
1825                         
1826                         /* Restore configuration. We need to do this
1827                            *after* the set_folder because the widget
1828                            memory asks the header view about its
1829                            folder  */
1830                         modest_widget_memory_restore (modest_runtime_get_conf (), 
1831                                                       G_OBJECT(header_view),
1832                                                       MODEST_CONF_HEADER_VIEW_KEY);
1833                 } else {
1834                         /* Update the active account */
1835                         modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1836                         /* Save only if we're seeing headers */
1837                         if (modest_main_window_get_contents_style (main_window) ==
1838                             MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1839                                 modest_widget_memory_save (conf, G_OBJECT (header_view), 
1840                                                            MODEST_CONF_HEADER_VIEW_KEY);
1841                         modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1842                 }
1843         }
1844
1845         /* Update toolbar dimming state */
1846         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1847 }
1848
1849 void 
1850 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1851                                      ModestWindow *win)
1852 {
1853         GtkWidget *dialog;
1854         gchar *txt, *item;
1855         gboolean online;
1856
1857         item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1858         
1859         online = tny_device_is_online (modest_runtime_get_device());
1860
1861         if (online) {
1862                 /* already online -- the item is simply not there... */
1863                 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1864                                                  GTK_DIALOG_MODAL,
1865                                                  GTK_MESSAGE_WARNING,
1866                                                  GTK_BUTTONS_OK,
1867                                                  _("The %s you selected cannot be found"),
1868                                                  item);
1869                 gtk_dialog_run (GTK_DIALOG(dialog));
1870         } else {
1871                 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1872                                                       GTK_WINDOW (win),
1873                                                       GTK_DIALOG_MODAL,
1874                                                       GTK_STOCK_CANCEL,
1875                                                       GTK_RESPONSE_REJECT,
1876                                                       GTK_STOCK_OK,
1877                                                       GTK_RESPONSE_ACCEPT,
1878                                                       NULL);
1879                 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1880                                          "Do you want to get online?"), item);
1881                 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1882                                     gtk_label_new (txt), FALSE, FALSE, 0);
1883                 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1884                 g_free (txt);
1885
1886                 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1887                 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1888                         /* TODO: Comment about why is this commented out: */
1889                         /* modest_platform_connect_and_wait (); */
1890                 }
1891         }
1892         gtk_widget_destroy (dialog);
1893 }
1894
1895 void
1896 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1897                                      ModestWindow *win)
1898 {
1899         /* g_message ("%s %s", __FUNCTION__, link); */
1900 }       
1901
1902
1903 void
1904 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1905                                         ModestWindow *win)
1906 {
1907         modest_platform_activate_uri (link);
1908 }
1909
1910 void
1911 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1912                                           ModestWindow *win)
1913 {
1914         modest_platform_show_uri_popup (link);
1915 }
1916
1917 void
1918 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1919                                              ModestWindow *win)
1920 {
1921         modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1922 }
1923
1924 void
1925 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1926                                           const gchar *address,
1927                                           ModestWindow *win)
1928 {
1929         /* g_message ("%s %s", __FUNCTION__, address); */
1930 }
1931
1932 void
1933 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1934 {
1935         TnyTransportAccount *transport_account;
1936         ModestMailOperation *mail_operation;
1937         MsgData *data;
1938         gchar *account_name, *from;
1939         ModestAccountMgr *account_mgr;
1940         gchar *info_text = NULL;
1941
1942         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1943         
1944         data = modest_msg_edit_window_get_msg_data (edit_window);
1945
1946         account_mgr = modest_runtime_get_account_mgr();
1947         account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1948         if (!account_name) 
1949                 account_name = modest_account_mgr_get_default_account (account_mgr);
1950         if (!account_name) {
1951                 g_printerr ("modest: no account found\n");
1952                 modest_msg_edit_window_free_msg_data (edit_window, data);
1953                 return;
1954         }
1955
1956         if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1957                 account_name = g_strdup (data->account_name);
1958         }
1959
1960         transport_account =
1961                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1962                                       (modest_runtime_get_account_store(),
1963                                        account_name,
1964                                        TNY_ACCOUNT_TYPE_TRANSPORT));
1965         if (!transport_account) {
1966                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1967                 g_free (account_name);
1968                 modest_msg_edit_window_free_msg_data (edit_window, data);
1969                 return;
1970         }
1971         from = modest_account_mgr_get_from_string (account_mgr, account_name);
1972
1973         /* Create the mail operation */         
1974         mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1975         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1976
1977         modest_mail_operation_save_to_drafts (mail_operation,
1978                                               transport_account,
1979                                               data->draft_msg,
1980                                               edit_window,
1981                                               from,
1982                                               data->to, 
1983                                               data->cc, 
1984                                               data->bcc,
1985                                               data->subject, 
1986                                               data->plain_body, 
1987                                               data->html_body,
1988                                               data->attachments,
1989                                               data->priority_flags);
1990         /* Frees */
1991         g_free (from);
1992         g_free (account_name);
1993         g_object_unref (G_OBJECT (transport_account));
1994         g_object_unref (G_OBJECT (mail_operation));
1995
1996         modest_msg_edit_window_free_msg_data (edit_window, data);
1997
1998         info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1999         modest_platform_information_banner (NULL, NULL, info_text);
2000         g_free (info_text);
2001 }
2002
2003 /* For instance, when clicking the Send toolbar button when editing a message: */
2004 void
2005 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2006 {
2007         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2008
2009         if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2010                 return;
2011         
2012         /* Offer the connection dialog, if necessary: */        
2013         if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2014                 return;
2015         
2016         /* FIXME: Code added just for testing. The final version will
2017            use the send queue provided by tinymail and some
2018            classifier */
2019         ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2020         gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2021         if (!account_name) 
2022                 account_name = modest_account_mgr_get_default_account (account_mgr);
2023                 
2024         if (!account_name) {
2025                 /* Run account setup wizard */
2026                 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2027                 return;
2028         }
2029         
2030         MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2031
2032         if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2033                 account_name = g_strdup (data->account_name);
2034         }
2035         
2036         /* Get the currently-active transport account for this modest account: */
2037         TnyTransportAccount *transport_account =
2038                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2039                                       (modest_runtime_get_account_store(),
2040                                        account_name));
2041         if (!transport_account) {
2042                 /* Run account setup wizard */
2043                 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2044                 return;
2045         }
2046         
2047         gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2048
2049         /* mail content checks and dialogs */
2050         if (data->subject == NULL || data->subject[0] == '\0') {
2051                 GtkResponseType response;
2052                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2053                                                                     _("mcen_nc_subject_is_empty_send"));
2054                 if (response == GTK_RESPONSE_CANCEL) {
2055                         g_free (account_name);
2056                         return;
2057                 }
2058         }
2059
2060         if (data->plain_body == NULL || data->plain_body[0] == '\0') {
2061                 GtkResponseType response;
2062                 gchar *note_message;
2063                 gchar *note_subject = data->subject;
2064                 if (note_subject == NULL || note_subject[0] == '\0')
2065                         note_subject = _("mail_va_no_subject");
2066                 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
2067                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2068                                                                     note_message);
2069                 g_free (note_message);
2070                 if (response == GTK_RESPONSE_CANCEL) {
2071                         g_free (account_name);
2072                         return;
2073                 }
2074         }
2075
2076         modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2077
2078         /* Create the mail operation */
2079         ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2080         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2081
2082         modest_mail_operation_send_new_mail (mail_operation,
2083                                              transport_account,
2084                                              data->draft_msg,
2085                                              from,
2086                                              data->to, 
2087                                              data->cc, 
2088                                              data->bcc,
2089                                              data->subject, 
2090                                              data->plain_body, 
2091                                              data->html_body,
2092                                              data->attachments,
2093                                              data->priority_flags);
2094                                              
2095         /* Free data: */
2096         g_free (from);
2097         g_free (account_name);
2098         g_object_unref (G_OBJECT (transport_account));
2099         g_object_unref (G_OBJECT (mail_operation));
2100
2101         modest_msg_edit_window_free_msg_data (edit_window, data);
2102         modest_msg_edit_window_set_sent (edit_window, TRUE);
2103
2104         /* Save settings and close the window: */
2105         modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2106 }
2107
2108 void 
2109 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2110                                   ModestMsgEditWindow *window)
2111 {
2112         ModestMsgEditFormatState *format_state = NULL;
2113
2114         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2115         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2116
2117         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2118                 return;
2119
2120         format_state = modest_msg_edit_window_get_format_state (window);
2121         g_return_if_fail (format_state != NULL);
2122
2123         format_state->bold = gtk_toggle_action_get_active (action);
2124         modest_msg_edit_window_set_format_state (window, format_state);
2125         g_free (format_state);
2126         
2127 }
2128
2129 void 
2130 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2131                                      ModestMsgEditWindow *window)
2132 {
2133         ModestMsgEditFormatState *format_state = NULL;
2134
2135         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2136         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2137
2138         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2139                 return;
2140
2141         format_state = modest_msg_edit_window_get_format_state (window);
2142         g_return_if_fail (format_state != NULL);
2143
2144         format_state->italics = gtk_toggle_action_get_active (action);
2145         modest_msg_edit_window_set_format_state (window, format_state);
2146         g_free (format_state);
2147         
2148 }
2149
2150 void 
2151 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2152                                      ModestMsgEditWindow *window)
2153 {
2154         ModestMsgEditFormatState *format_state = NULL;
2155
2156         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2157         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2158
2159         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2160                 return;
2161
2162         format_state = modest_msg_edit_window_get_format_state (window);
2163         g_return_if_fail (format_state != NULL);
2164
2165         format_state->bullet = gtk_toggle_action_get_active (action);
2166         modest_msg_edit_window_set_format_state (window, format_state);
2167         g_free (format_state);
2168         
2169 }
2170
2171 void 
2172 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2173                                      GtkRadioAction *selected,
2174                                      ModestMsgEditWindow *window)
2175 {
2176         ModestMsgEditFormatState *format_state = NULL;
2177         GtkJustification value;
2178
2179         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2180
2181         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2182                 return;
2183
2184         value = gtk_radio_action_get_current_value (selected);
2185
2186         format_state = modest_msg_edit_window_get_format_state (window);
2187         g_return_if_fail (format_state != NULL);
2188
2189         format_state->justification = value;
2190         modest_msg_edit_window_set_format_state (window, format_state);
2191         g_free (format_state);
2192 }
2193
2194 void 
2195 modest_ui_actions_on_select_editor_color (GtkAction *action,
2196                                           ModestMsgEditWindow *window)
2197 {
2198         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2199         g_return_if_fail (GTK_IS_ACTION (action));
2200
2201         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2202                 return;
2203
2204         modest_msg_edit_window_select_color (window);
2205 }
2206
2207 void 
2208 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2209                                                      ModestMsgEditWindow *window)
2210 {
2211         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2212         g_return_if_fail (GTK_IS_ACTION (action));
2213
2214         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2215                 return;
2216
2217         modest_msg_edit_window_select_background_color (window);
2218 }
2219
2220 void 
2221 modest_ui_actions_on_insert_image (GtkAction *action,
2222                                    ModestMsgEditWindow *window)
2223 {
2224         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2225         g_return_if_fail (GTK_IS_ACTION (action));
2226
2227         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2228                 return;
2229
2230         modest_msg_edit_window_insert_image (window);
2231 }
2232
2233 void 
2234 modest_ui_actions_on_attach_file (GtkAction *action,
2235                                   ModestMsgEditWindow *window)
2236 {
2237         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2238         g_return_if_fail (GTK_IS_ACTION (action));
2239
2240         modest_msg_edit_window_offer_attach_file (window);
2241 }
2242
2243 void 
2244 modest_ui_actions_on_remove_attachments (GtkAction *action,
2245                                          ModestMsgEditWindow *window)
2246 {
2247         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2248         g_return_if_fail (GTK_IS_ACTION (action));
2249
2250         modest_msg_edit_window_remove_attachments (window, NULL);
2251 }
2252
2253 static void
2254 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2255                                             gpointer user_data)
2256 {
2257         ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2258         const GError *error = modest_mail_operation_get_error (mail_op);
2259
2260         if(error)
2261         {
2262                 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2263                                                     modest_mail_operation_get_error (mail_op)->message);
2264         }
2265 }
2266
2267 static void
2268 modest_ui_actions_create_folder(GtkWidget *parent_window,
2269                                 GtkWidget *folder_view)
2270 {
2271         TnyFolderStore *parent_folder;
2272
2273         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2274         
2275         if (parent_folder) {
2276                 gboolean finished = FALSE;
2277                 gint result;
2278                 gchar *folder_name = NULL, *suggested_name = NULL;
2279                 const gchar *proto_str = NULL;
2280                 TnyAccount *account;
2281
2282                 if (TNY_IS_ACCOUNT (parent_folder))
2283                         account = g_object_ref (parent_folder);
2284                 else
2285                         account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2286                 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2287
2288                 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2289                     MODEST_PROTOCOL_STORE_POP) {
2290                         finished = TRUE;
2291                         hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2292                 }
2293                 g_object_unref (account);
2294
2295                 /* Run the new folder dialog */
2296                 while (!finished) {
2297                         result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2298                                                                         parent_folder,
2299                                                                         suggested_name,
2300                                                                         &folder_name);
2301
2302                         g_free (suggested_name);
2303                         suggested_name = NULL;
2304
2305                         if (result == GTK_RESPONSE_REJECT) {
2306                                 finished = TRUE;
2307                         } else {
2308                                 ModestMailOperation *mail_op;
2309                                 TnyFolder *new_folder = NULL;
2310
2311                                 mail_op  = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2312                                                                                           G_OBJECT(parent_window),
2313                                                                                           modest_ui_actions_new_folder_error_handler,
2314                                                                                           parent_window);
2315
2316                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
2317                                                                  mail_op);
2318                                 new_folder = modest_mail_operation_create_folder (mail_op,
2319                                                                                   parent_folder,
2320                                                                                   (const gchar *) folder_name);
2321                                 if (new_folder) {
2322                                         modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), 
2323                                                                           new_folder, TRUE);
2324
2325                                         g_object_unref (new_folder);
2326                                         finished = TRUE;
2327                                 }
2328                                 g_object_unref (mail_op);
2329                         }
2330
2331                         suggested_name = folder_name;
2332                         folder_name = NULL;
2333                 }
2334
2335                 g_object_unref (parent_folder);
2336         }
2337 }
2338
2339 void 
2340 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2341 {
2342         GtkWidget *folder_view;
2343         
2344         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2345
2346         folder_view = modest_main_window_get_child_widget (main_window,
2347                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2348         if (!folder_view)
2349                 return;
2350
2351         modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2352 }
2353
2354 static void
2355 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2356                                                gpointer user_data)
2357 {
2358         GObject *win = modest_mail_operation_get_source (mail_op);
2359         const GError *error = NULL;
2360         const gchar *message = NULL;
2361         
2362         /* Get error message */
2363         error = modest_mail_operation_get_error (mail_op);
2364         if (error != NULL && error->message != NULL) {
2365                 message = error->message;
2366         } else {
2367                 message = _("!!! FIXME: Unable to rename");
2368         }
2369         
2370         /* Show notification dialog */
2371         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2372         g_object_unref (win);
2373 }
2374
2375 void 
2376 modest_ui_actions_on_rename_folder (GtkAction *action,
2377                                      ModestMainWindow *main_window)
2378 {
2379         TnyFolderStore *folder;
2380         GtkWidget *folder_view;
2381         GtkWidget *header_view; 
2382
2383         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2384
2385         folder_view = modest_main_window_get_child_widget (main_window,
2386                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2387         if (!folder_view)
2388                 return;
2389
2390         header_view = modest_main_window_get_child_widget (main_window,
2391                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
2392         
2393         if (!header_view)
2394                 return;
2395
2396         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2397         if (!folder)
2398                 return;
2399
2400         /* Offer the connection dialog if necessary: */
2401         if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2402                 g_object_unref (G_OBJECT (folder));
2403                 return;
2404         }
2405
2406         
2407         if (TNY_IS_FOLDER (folder)) {
2408                 gchar *folder_name;
2409                 gint response;
2410                 const gchar *current_name;
2411
2412                 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2413                 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2414                                                                      current_name, &folder_name);
2415
2416                 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2417                         ModestMailOperation *mail_op;
2418
2419                         mail_op = 
2420                                 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO, 
2421                                                                                G_OBJECT(main_window),
2422                                                                                modest_ui_actions_rename_folder_error_handler,
2423                                                                                NULL);
2424
2425
2426                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2427                                                          mail_op);
2428
2429                         modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2430                         
2431                         modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2432                                                           TNY_FOLDER(folder), TRUE);
2433
2434
2435                         modest_header_view_clear ((ModestHeaderView *) header_view);
2436  
2437                         modest_mail_operation_rename_folder (mail_op,
2438                                                              TNY_FOLDER (folder),
2439                                                              (const gchar *) folder_name);
2440
2441                         g_object_unref (mail_op);
2442                         g_free (folder_name);
2443                 }
2444         }
2445         g_object_unref (folder);
2446 }
2447
2448 static void
2449 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2450                                                gpointer user_data)
2451 {
2452         GObject *win = modest_mail_operation_get_source (mail_op);
2453
2454         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2455                                                 _("mail_in_ui_folder_delete_error"));
2456         g_object_unref (win);
2457 }
2458
2459 static void
2460 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash) 
2461 {
2462         TnyFolderStore *folder;
2463         GtkWidget *folder_view;
2464         gint response;
2465         gchar *message;
2466         
2467         g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2468
2469         folder_view = modest_main_window_get_child_widget (main_window,
2470                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2471         if (!folder_view)
2472                 return;
2473
2474         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2475
2476         /* Show an error if it's an account */
2477         if (!TNY_IS_FOLDER (folder)) {
2478                 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2479                                                         _("mail_in_ui_folder_delete_error"));
2480                 g_object_unref (G_OBJECT (folder));
2481                 return ;
2482         }
2483
2484         /* Offer the connection dialog if necessary: */
2485         if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2486                 g_object_unref (G_OBJECT (folder));
2487                 return;
2488         }
2489
2490         /* Ask the user */      
2491         message =  g_strdup_printf (_("mcen_nc_delete_folder_text"), 
2492                                     tny_folder_get_name (TNY_FOLDER (folder)));
2493         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2494                                                             (const gchar *) message);
2495         g_free (message);
2496
2497         if (response == GTK_RESPONSE_OK) {
2498                 ModestMailOperation *mail_op = 
2499                         modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE, 
2500                                                                        G_OBJECT(main_window),
2501                                                                        modest_ui_actions_delete_folder_error_handler,
2502                                                                        NULL);
2503
2504                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2505                                                  mail_op);
2506                 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2507                 g_object_unref (G_OBJECT (mail_op));
2508         }
2509
2510         g_object_unref (G_OBJECT (folder));
2511 }
2512
2513 void 
2514 modest_ui_actions_on_delete_folder (GtkAction *action,
2515                                      ModestMainWindow *main_window)
2516 {
2517         GtkWidget *folder_view;
2518         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2519
2520         delete_folder (main_window, FALSE);
2521         folder_view = modest_main_window_get_child_widget (main_window,
2522                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2523         if (!folder_view)
2524                 return;
2525         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2526 }
2527
2528 void 
2529 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2530 {
2531         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2532         
2533         delete_folder (main_window, TRUE);
2534 }
2535
2536
2537 static void
2538 show_error (GtkWidget *parent_widget, const gchar* text)
2539 {
2540         hildon_banner_show_information(parent_widget, NULL, text);
2541         
2542 #if 0
2543         GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2544         /*
2545           GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2546           (GtkDialogFlags)0,
2547           GTK_MESSAGE_ERROR,
2548           GTK_BUTTONS_OK,
2549           text ));
2550         */
2551                  
2552         gtk_dialog_run (dialog);
2553         gtk_widget_destroy (GTK_WIDGET (dialog));
2554 #endif
2555 }
2556
2557 void
2558 modest_ui_actions_on_password_requested (TnyAccountStore *account_store, 
2559                                          const gchar* server_account_name,
2560                                          gchar **username,
2561                                          gchar **password, 
2562                                          gboolean *cancel, 
2563                                          gboolean *remember,
2564                                          ModestMainWindow *main_window)
2565 {
2566         g_return_if_fail(server_account_name);
2567         /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2568         
2569         /* Initalize output parameters: */
2570         if (cancel)
2571                 *cancel = FALSE;
2572                 
2573         if (remember)
2574                 *remember = TRUE;
2575                 
2576 #ifdef MODEST_PLATFORM_MAEMO
2577         /* Maemo uses a different (awkward) button order,
2578          * It should probably just use gtk_alternative_dialog_button_order ().
2579          */
2580         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2581                                               NULL,
2582                                               GTK_DIALOG_MODAL,
2583                                               GTK_STOCK_OK,
2584                                               GTK_RESPONSE_ACCEPT,
2585                                               GTK_STOCK_CANCEL,
2586                                               GTK_RESPONSE_REJECT,
2587                                               NULL);
2588 #else
2589         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2590                                               NULL,
2591                                               GTK_DIALOG_MODAL,
2592                                               GTK_STOCK_CANCEL,
2593                                               GTK_RESPONSE_REJECT,
2594                                               GTK_STOCK_OK,
2595                                               GTK_RESPONSE_ACCEPT,
2596                                               NULL);
2597 #endif /* MODEST_PLATFORM_MAEMO */
2598
2599         gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2600         
2601         gchar *server_name = modest_server_account_get_hostname (
2602                 modest_runtime_get_account_mgr(), server_account_name);
2603         if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2604                 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2605                 *cancel = TRUE;
2606                 return;
2607         }
2608         
2609         /* This causes a warning because the logical ID has no %s in it, 
2610          * though the translation does, but there is not much we can do about that: */
2611         gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2612         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2613                             FALSE, FALSE, 0);
2614         g_free (txt);
2615         g_free (server_name);
2616         server_name = NULL;
2617
2618         /* username: */
2619         gchar *initial_username = modest_server_account_get_username (
2620                 modest_runtime_get_account_mgr(), server_account_name);
2621         
2622         GtkWidget *entry_username = gtk_entry_new ();
2623         if (initial_username)
2624                 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2625         /* Dim this if a connection has ever succeeded with this username,
2626          * as per the UI spec: */
2627         const gboolean username_known = 
2628                 modest_server_account_get_username_has_succeeded(
2629                         modest_runtime_get_account_mgr(), server_account_name);
2630         gtk_widget_set_sensitive (entry_username, !username_known);
2631         
2632 #ifdef MODEST_PLATFORM_MAEMO
2633         /* Auto-capitalization is the default, so let's turn it off: */
2634         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2635         
2636         /* Create a size group to be used by all captions.
2637          * Note that HildonCaption does not create a default size group if we do not specify one.
2638          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2639         GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2640         
2641         GtkWidget *caption = hildon_caption_new (sizegroup, 
2642                 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2643         gtk_widget_show (entry_username);
2644         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
2645                 FALSE, FALSE, MODEST_MARGIN_HALF);
2646         gtk_widget_show (caption);
2647 #else 
2648         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2649                             TRUE, FALSE, 0);
2650 #endif /* MODEST_PLATFORM_MAEMO */      
2651                             
2652         /* password: */
2653         GtkWidget *entry_password = gtk_entry_new ();
2654         gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2655         /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2656         
2657 #ifdef MODEST_PLATFORM_MAEMO
2658         /* Auto-capitalization is the default, so let's turn it off: */
2659         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password), 
2660                 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2661         
2662         caption = hildon_caption_new (sizegroup, 
2663                 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2664         gtk_widget_show (entry_password);
2665         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
2666                 FALSE, FALSE, MODEST_MARGIN_HALF);
2667         gtk_widget_show (caption);
2668         g_object_unref (sizegroup);
2669 #else 
2670         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2671                             TRUE, FALSE, 0);
2672 #endif /* MODEST_PLATFORM_MAEMO */      
2673                                 
2674 /* This is not in the Maemo UI spec:
2675         remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2676         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2677                             TRUE, FALSE, 0);
2678 */
2679
2680         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2681         
2682         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2683                 if (username) {
2684                         *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2685                         
2686                         modest_server_account_set_username (
2687                                  modest_runtime_get_account_mgr(), server_account_name, 
2688                                  *username);
2689                                  
2690                         const gboolean username_was_changed = 
2691                                 (strcmp (*username, initial_username) != 0);
2692                         if (username_was_changed) {
2693                                 g_warning ("%s: tinymail does not yet support changing the "
2694                                         "username in the get_password() callback.\n", __FUNCTION__);
2695                         }
2696                 }
2697                         
2698                 if (password) {
2699                         *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2700                         
2701                         /* We do not save the password in the configuration, 
2702                          * because this function is only called for passwords that should 
2703                          * not be remembered:
2704                         modest_server_account_set_password (
2705                                  modest_runtime_get_account_mgr(), server_account_name, 
2706                                  *password);
2707                         */
2708                 }
2709                 
2710                 if (cancel)
2711                         *cancel   = FALSE;
2712                         
2713         } else {
2714                 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2715                 
2716                 if (username)
2717                         *username = NULL;
2718                         
2719                 if (password)
2720                         *password = NULL;
2721                         
2722                 if (cancel)
2723                         *cancel   = TRUE;
2724         }
2725
2726 /* This is not in the Maemo UI spec:
2727         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2728                 *remember = TRUE;
2729         else
2730                 *remember = FALSE;
2731 */
2732
2733         gtk_widget_destroy (dialog);
2734         
2735         /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2736 }
2737
2738 void
2739 modest_ui_actions_on_cut (GtkAction *action,
2740                           ModestWindow *window)
2741 {
2742         GtkWidget *focused_widget;
2743         GtkClipboard *clipboard;
2744
2745         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2746         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2747         if (GTK_IS_EDITABLE (focused_widget)) {
2748                 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2749                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2750                 gtk_clipboard_store (clipboard);
2751         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2752                 GtkTextBuffer *buffer;
2753
2754                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2755                 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2756                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2757                 gtk_clipboard_store (clipboard);
2758         } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2759                 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2760         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2761                 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2762         }
2763 }
2764
2765 void
2766 modest_ui_actions_on_copy (GtkAction *action,
2767                            ModestWindow *window)
2768 {
2769         GtkClipboard *clipboard;
2770         GtkWidget *focused_widget;
2771
2772         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2773         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2774
2775         if (GTK_IS_LABEL (focused_widget)) {
2776                 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2777                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2778                 gtk_clipboard_store (clipboard);
2779         } else if (GTK_IS_EDITABLE (focused_widget)) {
2780                 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2781                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2782                 gtk_clipboard_store (clipboard);
2783         } else if (GTK_IS_HTML (focused_widget)) {
2784                 gtk_html_copy (GTK_HTML (focused_widget));
2785                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2786                 gtk_clipboard_store (clipboard);
2787         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2788                 GtkTextBuffer *buffer;
2789                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2790                 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2791                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2792                 gtk_clipboard_store (clipboard);
2793         } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2794                 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2795                 TnyIterator *iter = tny_list_create_iterator (header_list);
2796                 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2797                 
2798                 gboolean ask = FALSE;
2799                 if (header) {
2800                         TnyFolder *folder = tny_header_get_folder (header);
2801                         TnyAccount *account = tny_folder_get_account (folder);
2802                         const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2803                         /* If it's POP then ask */
2804                         ask = (modest_protocol_info_get_transport_store_protocol (proto_str) == 
2805                                 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2806                         g_object_unref (account);
2807                         g_object_unref (folder);
2808                         g_object_unref (header);
2809                 }
2810
2811                 g_object_unref (iter);
2812                 
2813                 /* Check that the messages have been previously downloaded */
2814                 gboolean continue_download = TRUE;
2815                 if (ask)
2816                         continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE);
2817                 if (continue_download)
2818                         modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2819                 g_object_unref (header_list);
2820         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2821                 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2822         }    
2823
2824         /* Show information banner */
2825         modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2826         
2827 }
2828
2829 void
2830 modest_ui_actions_on_undo (GtkAction *action,
2831                            ModestWindow *window)
2832 {
2833         ModestEmailClipboard *clipboard = NULL;
2834
2835         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2836                 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2837         } else if (MODEST_IS_MAIN_WINDOW (window)) {
2838                 /* Clear clipboard source */
2839                 clipboard = modest_runtime_get_email_clipboard ();
2840                 modest_email_clipboard_clear (clipboard);               
2841         }
2842         else {
2843                 g_return_if_reached ();
2844         }
2845 }
2846
2847 void
2848 modest_ui_actions_on_redo (GtkAction *action,
2849                            ModestWindow *window)
2850 {
2851         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2852                 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2853         }
2854         else {
2855                 g_return_if_reached ();
2856         }
2857 }
2858
2859
2860 static void
2861 paste_msgs_cb (const GObject *object, gpointer user_data)
2862 {
2863         g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2864         g_return_if_fail (GTK_IS_WIDGET (user_data));
2865         
2866         /* destroy information note */
2867         gtk_widget_destroy (GTK_WIDGET(user_data));
2868 }
2869
2870 static void
2871 paste_as_attachment_free (gpointer data)
2872 {
2873         PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2874
2875         gtk_widget_destroy (helper->banner);
2876         g_object_unref (helper->banner);
2877         g_free (helper);
2878 }
2879
2880 static void
2881 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2882                             TnyHeader *header,
2883                             TnyMsg *msg,
2884                             gpointer userdata)
2885 {
2886         PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2887         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2888
2889         if (msg == NULL)
2890                 return;
2891
2892         modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2893         
2894 }
2895
2896 void
2897 modest_ui_actions_on_paste (GtkAction *action,
2898                             ModestWindow *window)
2899 {
2900         GtkWidget *focused_widget = NULL;
2901         GtkWidget *inf_note = NULL;
2902         ModestMailOperation *mail_op = NULL;
2903
2904         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2905         if (GTK_IS_EDITABLE (focused_widget)) {
2906                 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2907         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2908                 ModestEmailClipboard *e_clipboard = NULL;
2909                 e_clipboard = modest_runtime_get_email_clipboard ();
2910                 if (modest_email_clipboard_cleared (e_clipboard)) {
2911                         GtkTextBuffer *buffer;
2912                         GtkClipboard *clipboard;
2913
2914                         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2915                         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2916                         gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2917                 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2918                         ModestMailOperation *mail_op;
2919                         TnyFolder *src_folder;
2920                         TnyList *data;
2921                         gboolean delete;
2922                         PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2923                         helper->window = MODEST_MSG_EDIT_WINDOW (window);
2924                         helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2925                                                                            _CS("ckct_nw_pasting"));
2926                         modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2927                         mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
2928                                                              G_OBJECT (window));
2929                         if (helper->banner != NULL) {
2930                                 g_object_ref (G_OBJECT (helper->banner));
2931                                 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2932                                 gtk_widget_show (GTK_WIDGET (helper->banner));
2933                         }
2934
2935                         if (data != NULL) {
2936                                 modest_mail_operation_get_msgs_full (mail_op, 
2937                                                                      data,
2938                                                                      (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2939                                                                      helper,
2940                                                                      paste_as_attachment_free);
2941                         }
2942                 }
2943         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2944                 ModestEmailClipboard *clipboard = NULL;
2945                 TnyFolder *src_folder = NULL;
2946                 TnyFolderStore *folder_store = NULL;
2947                 TnyList *data = NULL;           
2948                 gboolean delete = FALSE;
2949                 
2950                 /* Check clipboard source */
2951                 clipboard = modest_runtime_get_email_clipboard ();
2952                 if (modest_email_clipboard_cleared (clipboard)) 
2953                         return;
2954                 
2955                 /* Get elements to paste */
2956                 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2957
2958                 /* Create a new mail operation */
2959                 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2960                 
2961                 /* Get destination folder */
2962                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2963
2964                 /* transfer messages  */
2965                 if (data != NULL) {
2966                         gint response = 0;
2967
2968                         /* Ask for user confirmation */
2969                         response = msgs_move_to_confirmation (GTK_WINDOW (window), 
2970                                                               TNY_FOLDER (folder_store), 
2971                                                               delete,
2972                                                               data);
2973                         
2974                         if (response == GTK_RESPONSE_OK) {
2975                                 /* Launch notification */
2976                                 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL, 
2977                                                                              _CS("ckct_nw_pasting"));
2978                                 if (inf_note != NULL)  {
2979                                         gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2980                                         gtk_widget_show (GTK_WIDGET(inf_note));
2981                                 }
2982
2983                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2984                                 modest_mail_operation_xfer_msgs (mail_op, 
2985                                                                  data,
2986                                                                  TNY_FOLDER (folder_store),
2987                                                                  delete,
2988                                                                  paste_msgs_cb,
2989                                                                  inf_note);                             
2990                         } else {
2991                                 g_object_unref (mail_op);
2992                         }
2993                         
2994                 } else if (src_folder != NULL) {                        
2995                         /* Launch notification */
2996                         inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL, 
2997                                                                      _CS("ckct_nw_pasting"));
2998                         if (inf_note != NULL)  {
2999                                 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3000                                 gtk_widget_show (GTK_WIDGET(inf_note));
3001                         }
3002                         
3003                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3004                         modest_mail_operation_xfer_folder (mail_op, 
3005                                                            src_folder,
3006                                                            folder_store,
3007                                                            delete,
3008                                                            paste_msgs_cb,
3009                                                            inf_note);
3010                 }
3011
3012                 /* Free */
3013                 if (data != NULL) 
3014                         g_object_unref (data);
3015                 if (src_folder != NULL) 
3016                         g_object_unref (src_folder);
3017                 if (folder_store != NULL) 
3018                         g_object_unref (folder_store);
3019         }
3020 }
3021
3022
3023 void
3024 modest_ui_actions_on_select_all (GtkAction *action,
3025                                  ModestWindow *window)
3026 {
3027         GtkWidget *focused_widget;
3028
3029         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3030         if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3031                 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3032         } else if (GTK_IS_LABEL (focused_widget)) {
3033                 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3034         } else if (GTK_IS_EDITABLE (focused_widget)) {
3035                 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3036         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3037                 GtkTextBuffer *buffer;
3038                 GtkTextIter start, end;
3039
3040                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3041                 gtk_text_buffer_get_start_iter (buffer, &start);
3042                 gtk_text_buffer_get_end_iter (buffer, &end);
3043                 gtk_text_buffer_select_range (buffer, &start, &end);
3044         } else if (GTK_IS_HTML (focused_widget)) {
3045                 gtk_html_select_all (GTK_HTML (focused_widget));
3046         } else if (MODEST_IS_MAIN_WINDOW (window)) {
3047                 GtkWidget *header_view = focused_widget;
3048                 GtkTreeSelection *selection = NULL;
3049                 
3050                 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3051                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3052                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
3053                                 
3054                 /* Select all messages */
3055                 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3056                 gtk_tree_selection_select_all (selection);
3057
3058                 /* Set focuse on header view */
3059                 gtk_widget_grab_focus (header_view);
3060         }
3061
3062 }
3063
3064 void
3065 modest_ui_actions_on_mark_as_read (GtkAction *action,
3066                                    ModestWindow *window)
3067 {       
3068         g_return_if_fail (MODEST_IS_WINDOW(window));
3069                 
3070         /* Mark each header as read */
3071         do_headers_action (window, headers_action_mark_as_read, NULL);
3072 }
3073
3074 void
3075 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3076                                      ModestWindow *window)
3077 {       
3078         g_return_if_fail (MODEST_IS_WINDOW(window));
3079                 
3080         /* Mark each header as read */
3081         do_headers_action (window, headers_action_mark_as_unread, NULL);
3082 }
3083
3084 void
3085 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3086                                   GtkRadioAction *selected,
3087                                   ModestWindow *window)
3088 {
3089         gint value;
3090
3091         value = gtk_radio_action_get_current_value (selected);
3092         if (MODEST_IS_WINDOW (window)) {
3093                 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3094         }
3095 }
3096
3097 void     modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3098                                                         GtkRadioAction *selected,
3099                                                         ModestWindow *window)
3100 {
3101         TnyHeaderFlags flags;
3102         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3103
3104         flags = gtk_radio_action_get_current_value (selected);
3105         modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3106 }
3107
3108 void     modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3109                                                            GtkRadioAction *selected,
3110                                                            ModestWindow *window)
3111 {
3112         gint file_format;
3113
3114         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3115
3116         file_format = gtk_radio_action_get_current_value (selected);
3117         modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3118 }
3119
3120
3121 void     
3122 modest_ui_actions_on_zoom_plus (GtkAction *action,
3123                                 ModestWindow *window)
3124 {
3125         g_return_if_fail (MODEST_IS_WINDOW (window));
3126
3127         modest_window_zoom_plus (MODEST_WINDOW (window));
3128 }
3129
3130 void     
3131 modest_ui_actions_on_zoom_minus (GtkAction *action,
3132                                  ModestWindow *window)
3133 {
3134         g_return_if_fail (MODEST_IS_WINDOW (window));
3135
3136         modest_window_zoom_minus (MODEST_WINDOW (window));
3137 }
3138
3139 void     
3140 modest_ui_actions_on_toggle_fullscreen    (GtkToggleAction *toggle,
3141                                            ModestWindow *window)
3142 {
3143         ModestWindowMgr *mgr;
3144         gboolean fullscreen, active;
3145         g_return_if_fail (MODEST_IS_WINDOW (window));
3146
3147         mgr = modest_runtime_get_window_mgr ();
3148
3149         active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3150         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3151
3152         if (active != fullscreen) {
3153                 modest_window_mgr_set_fullscreen_mode (mgr, active);
3154                 gtk_window_present (GTK_WINDOW (window));
3155         }
3156 }
3157
3158 void
3159 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3160                                         ModestWindow *window)
3161 {
3162         ModestWindowMgr *mgr;
3163         gboolean fullscreen;
3164
3165         g_return_if_fail (MODEST_IS_WINDOW (window));
3166
3167         mgr = modest_runtime_get_window_mgr ();
3168         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3169         modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3170
3171         gtk_window_present (GTK_WINDOW (window));
3172 }
3173
3174 /* 
3175  * Used by modest_ui_actions_on_details to call do_headers_action 
3176  */
3177 static void
3178 headers_action_show_details (TnyHeader *header, 
3179                              ModestWindow *window,
3180                              gpointer user_data)
3181
3182 {
3183         GtkWidget *dialog;
3184         
3185         /* Create dialog */
3186         dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3187
3188         /* Run dialog */
3189         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3190         gtk_widget_show_all (dialog);
3191         gtk_dialog_run (GTK_DIALOG (dialog));
3192
3193         gtk_widget_destroy (dialog);
3194 }
3195
3196 /*
3197  * Show the folder details in a ModestDetailsDialog widget
3198  */
3199 static void
3200 show_folder_details (TnyFolder *folder, 
3201                      GtkWindow *window)
3202 {
3203         GtkWidget *dialog;
3204         
3205         /* Create dialog */
3206         dialog = modest_details_dialog_new_with_folder (window, folder);
3207
3208         /* Run dialog */
3209         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3210         gtk_widget_show_all (dialog);
3211         gtk_dialog_run (GTK_DIALOG (dialog));
3212
3213         gtk_widget_destroy (dialog);
3214 }
3215
3216 /*
3217  * Show the header details in a ModestDetailsDialog widget
3218  */
3219 void     
3220 modest_ui_actions_on_details (GtkAction *action, 
3221                               ModestWindow *win)
3222 {
3223         TnyList * headers_list;
3224         TnyIterator *iter;
3225         TnyHeader *header;              
3226
3227         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3228                 TnyMsg *msg;
3229
3230                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3231                 if (!msg)
3232                         return;
3233                 g_object_unref (msg);           
3234
3235                 headers_list = get_selected_headers (win);
3236                 if (!headers_list)
3237                         return;
3238
3239                 iter = tny_list_create_iterator (headers_list);
3240
3241                 header = TNY_HEADER (tny_iterator_get_current (iter));
3242                 if (header) {
3243                         headers_action_show_details (header, win, NULL);
3244                         g_object_unref (header);
3245                 }
3246
3247                 g_object_unref (iter);
3248                 g_object_unref (headers_list);
3249
3250         } else if (MODEST_IS_MAIN_WINDOW (win)) {
3251                 GtkWidget *folder_view, *header_view;
3252
3253                 /* Check which widget has the focus */
3254                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3255                                                                     MODEST_WIDGET_TYPE_FOLDER_VIEW);
3256                 if (gtk_widget_is_focus (folder_view)) {
3257                         TnyFolderStore *folder_store
3258                                 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3259                         if (!folder_store) {
3260                                 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3261                                 return; 
3262                         }
3263                         /* Show only when it's a folder */
3264                         /* This function should not be called for account items, 
3265                          * because we dim the menu item for them. */
3266                         if (TNY_IS_FOLDER (folder_store)) {
3267                                 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3268                         }
3269
3270                         g_object_unref (folder_store);
3271
3272                 } else {
3273                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3274                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
3275                         /* Show details of each header */
3276                         do_headers_action (win, headers_action_show_details, header_view);
3277                 }
3278         }
3279 }
3280
3281 void     
3282 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3283                                      ModestMsgEditWindow *window)
3284 {
3285         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3286
3287         modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3288 }
3289
3290 void     
3291 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3292                                       ModestMsgEditWindow *window)
3293 {
3294         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3295
3296         modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3297 }
3298
3299 void
3300 modest_ui_actions_toggle_folders_view (GtkAction *action, 
3301                                        ModestMainWindow *main_window)
3302 {
3303         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3304
3305         if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3306                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3307         else
3308                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3309 }
3310
3311 void 
3312 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle, 
3313                                      ModestWindow *window)
3314 {
3315         gboolean active, fullscreen = FALSE;
3316         ModestWindowMgr *mgr;
3317
3318         active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3319
3320         /* Check if we want to toggle the toolbar vuew in fullscreen
3321            or normal mode */
3322         if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)), 
3323                      "ViewShowToolbarFullScreen")) {
3324                 fullscreen = TRUE;
3325         }
3326
3327         /* Toggle toolbar */
3328         mgr = modest_runtime_get_window_mgr ();
3329         modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3330 }
3331
3332 void     
3333 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3334                                            ModestMsgEditWindow *window)
3335 {
3336         modest_msg_edit_window_select_font (window);
3337 }
3338
3339 void
3340 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3341                                                   const gchar *display_name,
3342                                                   GtkWindow *window)
3343 {
3344         /* Do not change the application name if the widget has not
3345            the focus. This callback could be called even if the folder
3346            view has not the focus, because the handled signal could be
3347            emitted when the folder view is redrawn */
3348         if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3349                 if (display_name)
3350                         gtk_window_set_title (window, display_name);
3351                 else
3352                         gtk_window_set_title (window, " ");
3353         }
3354 }
3355
3356 void
3357 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3358 {
3359         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3360         modest_msg_edit_window_select_contacts (window);
3361 }
3362
3363 void
3364 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3365 {
3366         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3367         modest_msg_edit_window_check_names (window, FALSE);
3368 }
3369
3370 static void
3371 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3372 {
3373         modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3374                                          GTK_WIDGET (user_data));
3375 }
3376
3377 static GtkWidget*
3378 create_move_to_dialog (GtkWindow *win,
3379                        GtkWidget *folder_view,
3380                        GtkWidget **tree_view)
3381 {
3382         GtkWidget *dialog, *scroll;
3383         GtkWidget *new_button;
3384
3385         dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3386                                               GTK_WINDOW (win),
3387                                               GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3388                                               NULL);
3389
3390         gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3391         /* We do this manually so GTK+ does not associate a response ID for
3392          * the button. */
3393         new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3394         gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3395         gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3396
3397         /* Create scrolled window */
3398         scroll = gtk_scrolled_window_new (NULL, NULL);
3399         gtk_scrolled_window_set_policy  (GTK_SCROLLED_WINDOW (scroll),
3400                                          GTK_POLICY_AUTOMATIC,
3401                                          GTK_POLICY_AUTOMATIC);
3402
3403         /* Create folder view */
3404         *tree_view = modest_platform_create_folder_view (NULL);
3405
3406         g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3407
3408         /* It could happen that we're trying to move a message from a
3409            window (msg window for example) after the main window was
3410            closed, so we can not just get the model of the folder
3411            view */
3412         if (MODEST_IS_FOLDER_VIEW (folder_view))
3413                 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3414                                          gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3415         else
3416                 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view), 
3417                                                  TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3418
3419         modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3420         
3421         gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3422
3423         /* Add scroll to dialog */
3424         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), 
3425                             scroll, TRUE, TRUE, 0);
3426
3427         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3428         gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3429
3430         return dialog;
3431 }
3432
3433 /*
3434  * Returns TRUE if at least one of the headers of the list belongs to
3435  * a message that has been fully retrieved.
3436  */
3437 static gboolean
3438 has_retrieved_msgs (TnyList *list)
3439 {
3440         TnyIterator *iter;
3441         gboolean found = FALSE;
3442
3443         iter = tny_list_create_iterator (list);
3444         while (!tny_iterator_is_done (iter) && !found) {
3445                 TnyHeader *header;
3446                 TnyHeaderFlags flags = 0;
3447
3448                 header = TNY_HEADER (tny_iterator_get_current (iter));
3449                 if (header) {
3450                         flags = tny_header_get_flags (header);
3451                         if (flags & TNY_HEADER_FLAG_CACHED)
3452 /*                      if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3453                                 found = TRUE;
3454
3455                         g_object_unref (header);
3456                 }
3457
3458                 if (!found)
3459                         tny_iterator_next (iter);
3460         }
3461         g_object_unref (iter);
3462
3463         return found;
3464 }
3465
3466 /*
3467  * Shows a confirmation dialog to the user when we're moving messages
3468  * from a remote server to the local storage. Returns the dialog
3469  * response. If it's other kind of movement the it always returns
3470  * GTK_RESPONSE_OK
3471  */
3472 static gint
3473 msgs_move_to_confirmation (GtkWindow *win,
3474                            TnyFolder *dest_folder,
3475                            gboolean delete,
3476                            TnyList *headers)
3477 {
3478         gint response = GTK_RESPONSE_OK;
3479
3480         /* If the destination is a local folder (or MMC folder )*/
3481         if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3482 /*      if (modest_tny_folder_is_local_folder (dest_folder)) { */
3483                 TnyFolder *src_folder = NULL;
3484                 TnyIterator *iter = NULL;
3485                 TnyHeader *header = NULL;
3486
3487                 /* Get source folder */
3488                 iter = tny_list_create_iterator (headers);
3489                 header = TNY_HEADER (tny_iterator_get_current (iter));
3490                 if (header) {
3491                         src_folder = tny_header_get_folder (header);
3492                         g_object_unref (header);
3493                 }
3494
3495                 g_object_unref (iter);
3496
3497                 /* if no src_folder, message may be an attahcment */
3498                 if (src_folder == NULL) 
3499                         return GTK_RESPONSE_CANCEL;
3500
3501                 /* If the source is a remote folder */
3502 /*              if (!modest_tny_folder_is_local_folder (src_folder)) { */
3503                 if (modest_tny_folder_is_remote_folder (src_folder)) {
3504                         const gchar *message = NULL;
3505                         gboolean cached = has_retrieved_msgs (headers);
3506                         if (cached) 
3507                                 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3508                                                     tny_list_get_length (headers));
3509                         else 
3510                                 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3511                                                     tny_list_get_length (headers));
3512                         
3513                         if (cached && !delete)  
3514                                 response = GTK_RESPONSE_OK;
3515                         else
3516                                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3517                                                                                     (const gchar *) message);
3518                 }
3519                 
3520                 g_object_unref (src_folder);
3521         }
3522         
3523         return response;
3524 }
3525
3526
3527
3528 static void
3529 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3530 {
3531         ModestMsgViewWindow *self = NULL;
3532
3533         g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3534         self = MODEST_MSG_VIEW_WINDOW (object);
3535         
3536         if (!modest_msg_view_window_select_next_message (self))
3537                 if (!modest_msg_view_window_select_previous_message (self))
3538                         /* No more messages to view, so close this window */
3539                         modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3540 }
3541
3542 void
3543 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op, 
3544                                              gpointer user_data)
3545 {
3546         GObject *win = modest_mail_operation_get_source (mail_op);
3547         const GError *error = NULL;
3548         const gchar *message = NULL;
3549         
3550         /* Get error message */
3551         error = modest_mail_operation_get_error (mail_op);
3552         if (error != NULL && error->message != NULL) {
3553                 message = error->message;
3554         } else {
3555                 message = _("mail_in_ui_folder_move_target_error");
3556         }
3557         
3558         /* Show notification dialog */
3559         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3560         g_object_unref (win);
3561 }
3562
3563 void
3564 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op, 
3565                                               gpointer user_data)
3566 {
3567         GObject *win = modest_mail_operation_get_source (mail_op);
3568         const GError *error = modest_mail_operation_get_error (mail_op);
3569
3570         g_return_if_fail (error != NULL);
3571         if (error->message != NULL)             
3572                 g_printerr ("modest: %s\n", error->message);
3573         else
3574                 g_printerr ("modest: unkonw error on send&receive operation");
3575
3576         /* Show error message */
3577 /*      if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3578 /*              modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3579 /*                                                      _CS("sfil_ib_unable_to_receive")); */
3580 /*      else  */
3581 /*              modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3582 /*                                                      _CS("sfil_ib_unable_to_send")); */
3583         g_object_unref (win);
3584 }
3585
3586 static void
3587 open_msg_for_purge_cb (ModestMailOperation *mail_op, 
3588                        TnyHeader *header, 
3589                        TnyMsg *msg, 
3590                        gpointer user_data)
3591 {
3592         TnyList *parts;
3593         TnyIterator *iter;
3594         gint pending_purges = 0;
3595         gboolean some_purged = FALSE;
3596         ModestWindow *win = MODEST_WINDOW (user_data);
3597         ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3598
3599         /* If there was any error */
3600         if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3601                 modest_window_mgr_unregister_header (mgr, header);
3602                 return;
3603         }
3604
3605         /* Once the message has been retrieved for purging, we check if
3606          * it's all ok for purging */
3607
3608         parts = tny_simple_list_new ();
3609         tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3610         iter = tny_list_create_iterator (parts);
3611
3612         while (!tny_iterator_is_done (iter)) {
3613                 TnyMimePart *part;
3614                 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3615                 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3616                         if (tny_mime_part_is_purged (part))
3617                                 some_purged = TRUE;
3618                         else
3619                                 pending_purges++;
3620                 }
3621
3622                 if (part)
3623                         g_object_unref (part);
3624
3625                 tny_iterator_next (iter);
3626         }
3627
3628         if (pending_purges>0) {
3629                 gint response;
3630                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3631
3632                 if (response == GTK_RESPONSE_OK) {
3633                         modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3634                         tny_iterator_first (iter);
3635                         while (!tny_iterator_is_done (iter)) {
3636                                 TnyMimePart *part;
3637                                 
3638                                 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3639                                 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3640                                         tny_mime_part_set_purged (part);
3641
3642                                 if (part)
3643                                         g_object_unref (part);
3644
3645                                 tny_iterator_next (iter);
3646                         }
3647                         
3648                         tny_msg_rewrite_cache (msg);
3649                 }
3650         } else {
3651                 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3652         }
3653
3654         /* remove attachments */
3655         tny_iterator_first (iter);
3656         while (!tny_iterator_is_done (iter)) {
3657                 TnyMimePart *part;
3658                         
3659                 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3660                 if (part) {
3661                         /* One for the reference given by tny_iterator_get_current(): */
3662                         g_object_unref (part);
3663
3664                         /* TODO: Is this meant to remove the attachment by doing another unref()? 
3665                          * Otherwise, this seems useless. */
3666                 }
3667
3668                 tny_iterator_next (iter);
3669         }
3670         modest_window_mgr_unregister_header (mgr, header);
3671
3672         g_object_unref (iter);
3673         g_object_unref (parts);
3674 }
3675
3676 static void
3677 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3678                                                      ModestMainWindow *win)
3679 {
3680         GtkWidget *header_view;
3681         TnyList *header_list;
3682         TnyIterator *iter;
3683         TnyHeader *header;
3684         TnyHeaderFlags flags;
3685         ModestWindow *msg_view_window =  NULL;
3686         gboolean found;
3687
3688         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3689
3690         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3691                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
3692
3693         header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3694
3695         if (tny_list_get_length (header_list) == 1) {
3696                 iter = tny_list_create_iterator (header_list);
3697                 header = TNY_HEADER (tny_iterator_get_current (iter));
3698                 g_object_unref (iter);
3699         } else {
3700                 return;
3701         }
3702
3703         found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3704                                                           header, &msg_view_window);
3705         flags = tny_header_get_flags (header);
3706         if (!(flags & TNY_HEADER_FLAG_CACHED))
3707                 return;
3708         if (found) {
3709                 if (msg_view_window != NULL) 
3710                         modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3711                 else {
3712                         /* do nothing; uid was registered before, so window is probably on it's way */
3713                         g_warning ("debug: header %p has already been registered", header);
3714                 }
3715         } else {
3716                 ModestMailOperation *mail_op = NULL;
3717                 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3718                 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3719                                                                          G_OBJECT (win),
3720                                                                          modest_ui_actions_get_msgs_full_error_handler,
3721                                                                          NULL);
3722                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3723                 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3724                 
3725                 g_object_unref (mail_op);
3726         }
3727         if (header)
3728                 g_object_unref (header);
3729         if (header_list)
3730                 g_object_unref (header_list);
3731 }
3732
3733 /**
3734  * Utility function that transfer messages from both the main window
3735  * and the msg view window when using the "Move to" dialog
3736  */
3737 static void
3738 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3739                                               ModestWindow *win)
3740 {
3741         TnyList *headers = NULL;
3742         gint response = 0;
3743         TnyAccount *dst_account = NULL;
3744         const gchar *proto_str = NULL;
3745         gboolean dst_is_pop = FALSE;
3746
3747         if (!TNY_IS_FOLDER (dst_folder)) {
3748                 modest_platform_information_banner (GTK_WIDGET (win),
3749                                                     NULL,
3750                                                     _CS("ckdg_ib_unable_to_move_to_current_location"));
3751                 return;
3752         }
3753
3754         dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3755         proto_str = tny_account_get_proto (dst_account);
3756         dst_is_pop = (modest_protocol_info_get_transport_store_protocol (proto_str) == 
3757                       MODEST_PROTOCOL_STORE_POP);
3758         g_object_unref (dst_account);
3759
3760         /* Get selected headers */
3761         headers = get_selected_headers (MODEST_WINDOW (win));
3762
3763         if (dst_is_pop) {
3764                 modest_platform_information_banner (GTK_WIDGET (win),
3765                                                     NULL,
3766                                                     ngettext("mail_in_ui_folder_move_target_error",
3767                                                              "mail_in_ui_folder_move_targets_error",
3768                                                              tny_list_get_length (headers)));
3769                 g_object_unref (headers);
3770                 return;
3771         }
3772
3773         /* Ask for user confirmation */
3774         response = msgs_move_to_confirmation (GTK_WINDOW (win), 
3775                                               TNY_FOLDER (dst_folder), 
3776                                               TRUE,
3777                                               headers);
3778
3779         /* Transfer messages */
3780         if (response == GTK_RESPONSE_OK) {
3781                 ModestMailOperation *mail_op = 
3782                         modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
3783                                                                        G_OBJECT(win),
3784                                                                        modest_ui_actions_move_folder_error_handler,
3785                                                                        NULL);
3786                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
3787                                                  mail_op);
3788
3789                 modest_mail_operation_xfer_msgs (mail_op, 
3790                                                  headers,
3791                                                  TNY_FOLDER (dst_folder),
3792                                                  TRUE,
3793                                                  (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3794                                                  NULL);
3795
3796                 g_object_unref (G_OBJECT (mail_op));
3797         }
3798         g_object_unref (headers);
3799 }
3800
3801
3802 /*
3803  * UI handler for the "Move to" action when invoked from the
3804  * ModestMainWindow
3805  */
3806 static void 
3807 modest_ui_actions_on_main_window_move_to (GtkAction *action, 
3808                                           GtkWidget *folder_view,
3809                                           TnyFolderStore *dst_folder,
3810                                           ModestMainWindow *win)
3811 {
3812         GtkWidget *header_view = NULL;
3813         ModestMailOperation *mail_op = NULL;
3814         TnyFolderStore *src_folder;
3815
3816         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3817
3818         /* Get the source folder */
3819         src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3820         
3821         /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3822         if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), 
3823                                                                       src_folder))
3824                 goto end;
3825
3826         /* Get header view */
3827         header_view = 
3828                 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3829
3830         /* Get folder or messages to transfer */
3831         if (gtk_widget_is_focus (folder_view)) {
3832
3833                 /* Allow only to transfer folders to the local root folder */
3834                 if (TNY_IS_ACCOUNT (dst_folder) && 
3835                     !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3836                         goto end;
3837                 
3838                 /* Clean folder on header view before moving it */
3839                 modest_header_view_clear (MODEST_HEADER_VIEW (header_view)); 
3840
3841                 if (TNY_IS_FOLDER (src_folder)) {
3842                         mail_op = 
3843                                 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
3844                                                                                G_OBJECT(win),
3845                                                                                modest_ui_actions_move_folder_error_handler,
3846                                                                                NULL);
3847                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
3848                                                          mail_op);
3849
3850                         modest_mail_operation_xfer_folder (mail_op, 
3851                                                            TNY_FOLDER (src_folder),
3852                                                            dst_folder,
3853                                                            TRUE, NULL, NULL);
3854                         /* Unref mail operation */
3855                         g_object_unref (G_OBJECT (mail_op));
3856                 } else {
3857                         g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);       
3858                 }
3859         } else if (gtk_widget_is_focus (header_view)) {
3860                 /* Transfer messages */
3861                 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3862         }
3863         
3864  end:
3865     if (src_folder)
3866         g_object_unref (src_folder);
3867 }
3868
3869
3870 /*
3871  * UI handler for the "Move to" action when invoked from the
3872  * ModestMsgViewWindow
3873  */
3874 static void 
3875 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action, 
3876                                               TnyFolderStore *dst_folder,
3877                                               ModestMsgViewWindow *win)
3878 {
3879         TnyHeader *header = NULL;
3880         TnyFolder *src_folder;
3881
3882         /* Create header list */
3883         header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));              
3884         src_folder = tny_header_get_folder(header);
3885         g_object_unref (header);
3886
3887         /* Transfer the message */
3888         if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3889                 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3890
3891         g_object_unref (src_folder);
3892 }
3893
3894 void 
3895 modest_ui_actions_on_move_to (GtkAction *action, 
3896                               ModestWindow *win)
3897 {
3898         GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3899         gint result = 0;
3900         TnyFolderStore *dst_folder = NULL;
3901         ModestMainWindow *main_window;
3902
3903         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3904                           MODEST_IS_MSG_VIEW_WINDOW (win));
3905
3906         /* Get the main window if exists */
3907         if (MODEST_IS_MAIN_WINDOW (win))
3908                 main_window = MODEST_MAIN_WINDOW (win);
3909         else
3910                 main_window = 
3911                         MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3912
3913         /* Get the folder view widget if exists */
3914         if (main_window)
3915                 folder_view = modest_main_window_get_child_widget (main_window,
3916                                                                    MODEST_WIDGET_TYPE_FOLDER_VIEW);
3917         else
3918                 folder_view = NULL;
3919
3920         /* Create and run the dialog */
3921         dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3922         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3923         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3924         result = gtk_dialog_run (GTK_DIALOG(dialog));
3925         g_object_ref (tree_view);
3926         gtk_widget_destroy (dialog);
3927
3928         if (result != GTK_RESPONSE_ACCEPT)
3929                 return;
3930
3931         dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3932         /* Offer the connection dialog if necessary: */
3933         if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), 
3934                                                                       dst_folder)) {
3935
3936                 /* Do window specific stuff */
3937                 if (MODEST_IS_MAIN_WINDOW (win))
3938                         modest_ui_actions_on_main_window_move_to (action,
3939                                                                   folder_view,
3940                                                                   dst_folder,
3941                                                                   MODEST_MAIN_WINDOW (win));
3942                 else
3943                         modest_ui_actions_on_msg_view_window_move_to (action,
3944                                                                       dst_folder,
3945                                                                       MODEST_MSG_VIEW_WINDOW (win));
3946         }
3947         if (dst_folder)
3948                 g_object_unref (dst_folder);
3949 }
3950
3951 /*
3952  * Calls #HeadersFunc for each header already selected in the main
3953  * window or the message currently being shown in the msg view window
3954  */
3955 static void
3956 do_headers_action (ModestWindow *win, 
3957                    HeadersFunc func,
3958                    gpointer user_data)
3959 {
3960         TnyList *headers_list = NULL;
3961         TnyIterator *iter = NULL;
3962         TnyHeader *header = NULL;
3963         TnyFolder *folder = NULL;
3964
3965         /* Get headers */
3966         headers_list = get_selected_headers (win);
3967         if (!headers_list)
3968                 return;
3969
3970         /* Get the folder */
3971         iter = tny_list_create_iterator (headers_list);
3972         header = TNY_HEADER (tny_iterator_get_current (iter));
3973         if (header) {
3974                 folder = tny_header_get_folder (header);
3975                 g_object_unref (header);
3976         }
3977
3978         /* Call the function for each header */
3979         while (!tny_iterator_is_done (iter)) {
3980                 header = TNY_HEADER (tny_iterator_get_current (iter));
3981                 func (header, win, user_data);
3982                 g_object_unref (header);
3983                 tny_iterator_next (iter);
3984         }
3985
3986         /* Trick: do a poke status in order to speed up the signaling
3987            of observers */
3988         tny_folder_poke_status (folder);
3989
3990         /* Frees */
3991         g_object_unref (folder);
3992         g_object_unref (iter);
3993         g_object_unref (headers_list);
3994 }
3995
3996 void 
3997 modest_ui_actions_view_attachment (GtkAction *action,
3998                                    ModestWindow *window)
3999 {
4000         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4001                 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4002         } else {
4003                 /* not supported window for this action */
4004                 g_return_if_reached ();
4005         }
4006 }
4007
4008 void
4009 modest_ui_actions_save_attachments (GtkAction *action,
4010                                     ModestWindow *window)
4011 {
4012         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4013                 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4014         } else {
4015                 /* not supported window for this action */
4016                 g_return_if_reached ();
4017         }
4018 }
4019
4020 void
4021 modest_ui_actions_remove_attachments (GtkAction *action,
4022                                       ModestWindow *window)
4023 {
4024         if (MODEST_IS_MAIN_WINDOW (window)) {
4025                 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4026         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4027                 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4028         } else {
4029                 /* not supported window for this action */
4030                 g_return_if_reached ();
4031         }
4032 }
4033
4034 void 
4035 modest_ui_actions_on_settings (GtkAction *action, 
4036                                ModestWindow *win)
4037 {
4038         GtkWidget *dialog;
4039
4040         dialog = modest_platform_get_global_settings_dialog ();
4041         gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4042         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4043         gtk_widget_show_all (dialog);
4044
4045         gtk_dialog_run (GTK_DIALOG (dialog));
4046
4047         gtk_widget_destroy (dialog);
4048 }
4049
4050 void 
4051 modest_ui_actions_on_help (GtkAction *action, 
4052                            ModestWindow *win)
4053 {
4054         const gchar *help_id = NULL;
4055
4056         if (MODEST_IS_MAIN_WINDOW (win)) {
4057                 const gchar *action_name;
4058                 action_name = gtk_action_get_name (action);
4059
4060                 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4061                     !strcmp (action_name, "HeaderViewCSMHelp")) {
4062                         GtkWidget *folder_view;
4063                         TnyFolderStore *folder_store;
4064                         /* Get selected folder */
4065                         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4066                                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
4067                         folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4068
4069                         /* Switch help_id */
4070                         if (TNY_IS_FOLDER (folder_store)) {
4071                                 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4072                                 case TNY_FOLDER_TYPE_NORMAL:
4073                                         help_id = "applications_email_managefolders";
4074                                         break;
4075                                 case TNY_FOLDER_TYPE_INBOX:
4076                                         help_id = "applications_email_inbox";
4077                                         break;
4078                                 case TNY_FOLDER_TYPE_OUTBOX:
4079                                         help_id = "applications_email_outbox";
4080                                         break;
4081                                 case TNY_FOLDER_TYPE_SENT:
4082                                         help_id = "applications_email_sent";
4083                                         break;
4084                                 case TNY_FOLDER_TYPE_DRAFTS:
4085                                         help_id = "applications_email_drafts";
4086                                         break;
4087                                 case TNY_FOLDER_TYPE_ARCHIVE:
4088                                         help_id = "applications_email_managefolders";
4089                                         break;
4090                                 default:
4091                                         help_id = "applications_email_managefolders";
4092                                 }
4093                         } else {
4094                                 help_id = "applications_email_mainview";        
4095                         }
4096                         g_object_unref (folder_store);
4097                 } else {
4098                         help_id = "applications_email_mainview";        
4099                 }
4100         } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4101                 help_id = "applications_email_viewer";
4102         } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4103                 help_id = "applications_email_editor";
4104
4105         modest_platform_show_help (GTK_WINDOW (win), help_id);
4106 }
4107
4108 void 
4109 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4110                                             ModestWindow *window)
4111 {
4112         ModestMailOperation *mail_op;
4113         TnyList *headers;
4114
4115         /* Get headers */
4116         headers = get_selected_headers (window);
4117         if (!headers)
4118                 return;
4119
4120         /* Create mail operation */
4121         mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
4122                                                                  G_OBJECT (window),
4123                                                                  modest_ui_actions_get_msgs_full_error_handler, 
4124                                                                  NULL);
4125         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4126         modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4127
4128         /* Frees */
4129         g_object_unref (headers);
4130         g_object_unref (mail_op);
4131 }
4132
4133 void
4134 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4135                                           ModestWindow *window)
4136 {
4137         g_return_if_fail (MODEST_IS_WINDOW (window));
4138         
4139         /* Update dimmed */     
4140         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4141 }
4142
4143 void
4144 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4145                                           ModestWindow *window)
4146 {
4147         g_return_if_fail (MODEST_IS_WINDOW (window));
4148
4149         /* Update dimmed */     
4150         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4151 }
4152
4153 void
4154 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4155                                           ModestWindow *window)
4156 {
4157         g_return_if_fail (MODEST_IS_WINDOW (window));
4158
4159         /* Update dimmed */     
4160         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4161 }
4162
4163 void
4164 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4165                                           ModestWindow *window)
4166 {
4167         g_return_if_fail (MODEST_IS_WINDOW (window));
4168
4169         /* Update dimmed */     
4170         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4171 }
4172
4173 void
4174 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4175                                           ModestWindow *window)
4176 {
4177         g_return_if_fail (MODEST_IS_WINDOW (window));
4178
4179         /* Update dimmed */     
4180         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4181 }
4182
4183 void
4184 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4185                                                  ModestWindow *window)
4186 {
4187         g_return_if_fail (MODEST_IS_WINDOW (window));
4188
4189         /* Update dimmed */     
4190         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4191 }
4192
4193 void
4194 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4195                                                      ModestWindow *window)
4196 {
4197         g_return_if_fail (MODEST_IS_WINDOW (window));
4198
4199         /* Update dimmed */     
4200         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4201 }
4202
4203 void
4204 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4205                                                      ModestWindow *window)
4206 {
4207         g_return_if_fail (MODEST_IS_WINDOW (window));
4208
4209         /* Update dimmed */     
4210         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4211 }
4212
4213 void
4214 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4215 {
4216         g_return_if_fail (MODEST_IS_WINDOW (window));
4217
4218         /* Update dimmed */     
4219         modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");  
4220 }
4221
4222 void
4223 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4224 {
4225         g_return_if_fail (MODEST_IS_WINDOW (window));
4226
4227         modest_platform_show_search_messages (GTK_WINDOW (window));
4228 }
4229
4230 void     
4231 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4232 {
4233         g_return_if_fail (MODEST_IS_WINDOW (win));
4234         modest_platform_show_addressbook (GTK_WINDOW (win));
4235 }
4236
4237
4238 void
4239 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4240                                           ModestWindow *window)
4241 {
4242         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4243
4244         modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4245 }
4246
4247 static void 
4248 _on_send_receive_progress_changed (ModestMailOperation  *mail_op, 
4249                                    ModestMailOperationState *state,
4250                                    gpointer user_data)
4251 {
4252         g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4253
4254         /* Set send/receive operation finished */       
4255         if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4256                 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));
4257         
4258 }
4259
4260