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