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