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