Don't ask for confirmation on modest_ui_actions_xfer_messages_from_move_to(), it...
[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 _MoveToHelper {
107         ModestMailOperation *mail_op;
108         TnyFolder *folder;
109 } MoveToHelper;
110
111 typedef struct _PasteAsAttachmentHelper {
112         ModestMsgEditWindow *window;
113         GtkWidget *banner;
114 } PasteAsAttachmentHelper;
115
116
117 /*
118  * The do_headers_action uses this kind of functions to perform some
119  * action to each member of a list of headers
120  */
121 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
122
123 static void     do_headers_action     (ModestWindow *win, 
124                                        HeadersFunc func,
125                                        gpointer user_data);
126
127 static void     open_msg_cb            (ModestMailOperation *mail_op, 
128                                         TnyHeader *header, 
129                                         TnyMsg *msg,
130                                         gpointer user_data);
131
132 static void     reply_forward_cb       (ModestMailOperation *mail_op, 
133                                         TnyHeader *header, 
134                                         TnyMsg *msg,
135                                         gpointer user_data);
136
137 static void     reply_forward          (ReplyForwardAction action, ModestWindow *win);
138
139 static void     folder_refreshed_cb    (ModestMailOperation *mail_op, 
140                                         TnyFolder *folder, 
141                                         gpointer user_data);
142
143 static void     _on_send_receive_progress_changed (ModestMailOperation  *mail_op, 
144                                                    ModestMailOperationState *state,
145                                                    gpointer user_data);
146
147 static gint header_list_count_uncached_msgs (TnyList *header_list);
148 static gboolean connect_to_get_msg (
149                                                 GtkWindow *win,
150                                                 gint num_of_uncached_msgs);
151
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         GtkDialog *wizard;
162         
163         wizard = modest_window_mgr_get_easysetup_dialog
164                 (modest_runtime_get_window_mgr());
165         if (wizard) {
166                 /* old wizard is active already; present it and
167                  * act as if the user cancelled the non-existing
168                  * new one
169                  */
170                 printf ("wizard already active\n");
171                 return FALSE;
172         } else {
173                 /* there is no such wizard yet */
174                 wizard = GTK_DIALOG(modest_easysetup_wizard_dialog_new ());
175                 modest_window_mgr_set_easysetup_dialog
176                         (modest_runtime_get_window_mgr(), GTK_DIALOG(wizard));
177         } 
178
179         
180         /* always present a main window in the background 
181          * we do it here, so we cannot end up with to wizards (as this
182          * function might be called in modest_window_mgr_get_main_window as well */
183         if (!win) 
184                 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr());
185
186         /* make sure the mainwindow is visible */
187         gtk_widget_show_all (GTK_WIDGET(win));
188         gtk_window_present (GTK_WINDOW(win));
189
190         
191         gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
192
193         /* Don't make this a modal window, because secondary windows will then 
194          * be unusable, freezing the UI: */
195         /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
196         
197         gint dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
198         if (dialog_response == GTK_RESPONSE_CANCEL)
199                 result = FALSE;
200         else {
201                 /* Check whether an account was created: */
202                 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
203         }
204         
205         gtk_widget_destroy (GTK_WIDGET (wizard));
206
207         /* clear it from the window mgr */
208         modest_window_mgr_set_easysetup_dialog
209                 (modest_runtime_get_window_mgr(), NULL);
210         
211         return result;
212 }
213
214
215 void   
216 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
217 {
218         GtkWidget *about;
219         const gchar *authors[] = {
220                 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
221                 NULL
222         };
223         about = gtk_about_dialog_new ();
224         gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
225         gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
226         gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
227                                         _("Copyright (c) 2006, Nokia Corporation\n"
228                                           "All rights reserved."));
229         gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
230                                        _("a modest e-mail client\n\n"
231                                          "design and implementation: Dirk-Jan C. Binnema\n"
232                                          "contributions from the fine people at KC and Ig\n"
233                                          "uses the tinymail email framework written by Philip van Hoof"));
234         gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
235         gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
236         gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
237         gtk_window_set_modal (GTK_WINDOW (about), TRUE);
238         
239         gtk_dialog_run (GTK_DIALOG (about));
240         gtk_widget_destroy(about);
241 }
242
243 /*
244  * Gets the list of currently selected messages. If the win is the
245  * main window, then it returns a newly allocated list of the headers
246  * selected in the header view. If win is the msg view window, then
247  * the value returned is a list with just a single header.
248  *
249  * The caller of this funcion must free the list.
250  */
251 static TnyList *
252 get_selected_headers (ModestWindow *win)
253 {
254         if (MODEST_IS_MAIN_WINDOW(win)) {
255                 GtkWidget *header_view;         
256                 
257                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
258                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
259                 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
260                 
261         } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
262                 /* for MsgViewWindows, we simply return a list with one element */
263                 TnyHeader *header;
264                 TnyList *list = NULL;
265                 
266                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
267                 if (header != NULL) {
268                         list = tny_simple_list_new ();
269                         tny_list_prepend (list, G_OBJECT(header));
270                         g_object_unref (G_OBJECT(header));
271                 }
272
273                 return list;
274
275         } else
276                 return NULL;
277 }
278
279 static void
280 headers_action_mark_as_read (TnyHeader *header,
281                              ModestWindow *win,
282                              gpointer user_data)
283 {
284         TnyHeaderFlags flags;
285
286         g_return_if_fail (TNY_IS_HEADER(header));
287
288         flags = tny_header_get_flags (header);
289         if (flags & TNY_HEADER_FLAG_SEEN) return;
290         tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
291 }
292
293 static void
294 headers_action_mark_as_unread (TnyHeader *header,
295                                ModestWindow *win,
296                                gpointer user_data)
297 {
298         TnyHeaderFlags flags;
299
300         g_return_if_fail (TNY_IS_HEADER(header));
301
302         flags = tny_header_get_flags (header);
303         if (flags & TNY_HEADER_FLAG_SEEN)  {
304                 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
305         }
306 }
307
308 /** A convenience method, because deleting a message is 
309  * otherwise complicated, and it's best to change it in one place 
310  * when we change it.
311  */
312 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
313 {
314         ModestMailOperation *mail_op = NULL;
315         mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, 
316                 win ? G_OBJECT(win) : NULL);
317         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
318                                          mail_op);
319         
320         /* Always delete. TODO: Move to trash still not supported */
321         modest_mail_operation_remove_msg (mail_op, header, FALSE);
322         g_object_unref (G_OBJECT (mail_op));
323 }
324
325 /** A convenience method, because deleting a message is 
326  * otherwise complicated, and it's best to change it in one place 
327  * when we change it.
328  */
329 void modest_do_messages_delete (TnyList *headers, ModestWindow *win)
330 {
331         ModestMailOperation *mail_op = NULL;
332         mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, 
333                 win ? G_OBJECT(win) : NULL);
334         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
335                                          mail_op);
336         
337         /* Always delete. TODO: Move to trash still not supported */
338         modest_mail_operation_remove_msgs (mail_op, headers, FALSE);
339         g_object_unref (G_OBJECT (mail_op));
340 }
341
342 /* static void */
343 /* headers_action_delete (TnyHeader *header, */
344 /*                     ModestWindow *win, */
345 /*                     gpointer user_data) */
346 /* { */
347 /*      modest_do_message_delete (header, win); */
348
349 /* } */
350
351 /** After deleing a message that is currently visible in a window, 
352  * show the next message from the list, or close the window if there are no more messages.
353  **/
354 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
355 {
356         /* Close msg view window or select next */
357         if (modest_msg_view_window_last_message_selected (win) &&
358                 modest_msg_view_window_first_message_selected (win)) {
359                 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
360         } else {
361                 if (!modest_msg_view_window_select_next_message (win)) {
362                         gboolean ret_value;
363                         g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
364                 }
365         }
366 }
367
368 void
369 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
370 {
371         TnyList *header_list = NULL;
372         TnyIterator *iter = NULL;
373         TnyHeader *header = NULL;
374         gchar *message = NULL;
375         gchar *desc = NULL;
376         gint response;
377         ModestWindowMgr *mgr;
378         GtkWidget *header_view = NULL;
379
380         g_return_if_fail (MODEST_IS_WINDOW(win));
381         
382         /* Check first if the header view has the focus */
383         if (MODEST_IS_MAIN_WINDOW (win)) {
384                 header_view = 
385                         modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
386                                                              MODEST_WIDGET_TYPE_HEADER_VIEW);
387                 if (!gtk_widget_is_focus (header_view))
388                         return;
389         }
390         
391         /* Get the headers, either from the header view (if win is the main window),
392          * or from the message view window: */
393         header_list = get_selected_headers (win);
394         if (!header_list) return;
395                         
396         /* Check if any of the headers are already opened, or in the process of being opened */
397         if (MODEST_IS_MAIN_WINDOW (win)) {
398                 gboolean found;
399                 iter = tny_list_create_iterator (header_list);
400                 found = FALSE;
401                 mgr = modest_runtime_get_window_mgr ();
402                 while (!tny_iterator_is_done (iter) && !found) {
403                         header = TNY_HEADER (tny_iterator_get_current (iter));
404                         if (header) {
405                                 found =  modest_window_mgr_find_registered_header (mgr, header, NULL);
406                                 g_object_unref (header);
407                         }
408
409                         tny_iterator_next (iter);
410                 }
411                 g_object_unref (iter);
412
413                 if (found) {
414                         gchar *num, *msg;
415
416                         num = g_strdup_printf ("%d", tny_list_get_length (header_list));
417                         msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
418
419                         modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
420                         
421                         g_free (msg);
422                         g_free (num);
423                         g_object_unref (header_list);
424                         return;
425                 }
426         }
427
428         /* Select message */
429         if (tny_list_get_length(header_list) == 1) {
430                 iter = tny_list_create_iterator (header_list);
431                 header = TNY_HEADER (tny_iterator_get_current (iter));
432                 if (header) {
433                         desc = g_strdup_printf ("%s", tny_header_get_subject (header)); 
434                         g_object_unref (header);
435                 }
436
437                 g_object_unref (iter);
438         }
439         message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages", 
440                                            tny_list_get_length(header_list)), desc);
441
442         /* Confirmation dialog */
443         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
444                                                             message);
445         
446
447         if (response == GTK_RESPONSE_OK) {      
448                 ModestWindow *main_window = NULL;
449                 ModestWindowMgr *mgr = NULL;
450                 GtkTreeModel *model = NULL;
451                 GtkTreeSelection *sel = NULL;
452                 GList *sel_list = NULL, *tmp = NULL;
453                 GtkTreeRowReference *next_row_reference = NULL;
454                 GtkTreeRowReference *prev_row_reference = NULL;
455                 GtkTreePath *next_path = NULL;
456                 GtkTreePath *prev_path = NULL;
457                 GError *err = NULL;
458
459                 /* Find last selected row */                    
460                 if (MODEST_IS_MAIN_WINDOW (win)) {
461                         model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
462                         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
463                         sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
464                         for (tmp=sel_list; tmp; tmp=tmp->next) {
465                                 if (tmp->next == NULL) {
466                                         prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
467                                         next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
468
469                                         gtk_tree_path_prev (prev_path);
470                                         gtk_tree_path_next (next_path);
471
472                                         prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
473                                         next_row_reference = gtk_tree_row_reference_new (model, next_path);
474                                 }
475                         }
476                 }
477                 
478                 /* Disable window dimming management */
479                 modest_window_disable_dimming (MODEST_WINDOW(win));
480
481                 /* Remove each header. If it's a view window header_view == NULL */
482                 modest_do_messages_delete (header_list, win);
483                 
484                 /* Enable window dimming management */
485                 gtk_tree_selection_unselect_all (sel);
486                 modest_window_enable_dimming (MODEST_WINDOW(win));
487                 
488                 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
489                         modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
490                         
491                         /* Get main window */
492                         mgr = modest_runtime_get_window_mgr ();
493                         main_window = modest_window_mgr_get_main_window (mgr);
494                 }
495                 else {                  
496                         /* Move cursor to next row */
497                         main_window = win; 
498
499                         /* Select next or previous row */
500                         if (gtk_tree_row_reference_valid (next_row_reference)) {
501 /*                              next_path = gtk_tree_row_reference_get_path (row_reference); */
502                                 gtk_tree_selection_select_path (sel, next_path);
503                         }
504                         else if (gtk_tree_row_reference_valid (prev_row_reference)) {                           
505                                 gtk_tree_selection_select_path (sel, prev_path);
506                         }
507
508                         /* Free */
509                         if (next_row_reference != NULL) 
510                                 gtk_tree_row_reference_free (next_row_reference);
511                         if (next_path != NULL) 
512                                 gtk_tree_path_free (next_path);                         
513                         if (prev_row_reference != NULL) 
514                                 gtk_tree_row_reference_free (prev_row_reference);
515                         if (prev_path != NULL) 
516                                 gtk_tree_path_free (prev_path);                         
517                 }
518
519                 if (err != NULL) {
520                         printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
521                         g_error_free(err);
522                 }
523                 
524                 /* Update toolbar dimming state */
525                 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
526
527                 /* Free */
528                 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
529                 g_list_free (sel_list);
530         }
531
532         /* Free*/
533         g_free(message);
534         g_free(desc);
535         g_object_unref (header_list);
536 }
537
538
539
540
541 /* delete either message or folder, based on where we are */
542 void
543 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
544 {
545         g_return_if_fail (MODEST_IS_WINDOW(win));
546         
547         /* Check first if the header view has the focus */
548         if (MODEST_IS_MAIN_WINDOW (win)) {
549                 GtkWidget *w;
550                 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
551                                                          MODEST_WIDGET_TYPE_FOLDER_VIEW);
552                 if (gtk_widget_is_focus (w)) {
553                         modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
554                         return;
555                 }
556         }
557         modest_ui_actions_on_delete_message (action, win);
558 }
559
560
561
562 void
563 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
564 {       
565         ModestWindowMgr *mgr = NULL;
566         
567 #ifdef MODEST_PLATFORM_MAEMO
568         modest_osso_save_state();
569 #endif /* MODEST_PLATFORM_MAEMO */
570
571         g_debug ("closing down, clearing %d item(s) from operation queue",
572                  modest_mail_operation_queue_num_elements
573                  (modest_runtime_get_mail_operation_queue()));
574
575         /* cancel all outstanding operations */
576         modest_mail_operation_queue_cancel_all 
577                 (modest_runtime_get_mail_operation_queue());
578         
579         g_debug ("queue has been cleared");
580
581
582         /* Check if there are opened editing windows */ 
583         mgr = modest_runtime_get_window_mgr ();
584         modest_window_mgr_close_all_windows (mgr);
585
586         /* note: when modest-tny-account-store is finalized,
587            it will automatically set all network connections
588            to offline */
589
590 /*      gtk_main_quit (); */
591 }
592
593 void
594 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
595 {
596         gboolean ret_value;
597
598         g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
599
600 /*      if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
601 /*              gtk_widget_destroy (GTK_WIDGET (win)); */
602 /*      } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
603 /*              gboolean ret_value; */
604 /*              g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
605 /*      } else if (MODEST_IS_WINDOW (win)) { */
606 /*              gtk_widget_destroy (GTK_WIDGET (win)); */
607 /*      } else { */
608 /*              g_return_if_reached (); */
609 /*      } */
610 }
611
612 void
613 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
614 {
615         GtkClipboard *clipboard = NULL;
616         gchar *selection = NULL;
617
618         clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
619         selection = gtk_clipboard_wait_for_text (clipboard);
620
621         /* Question: why is the clipboard being used here? 
622          * It doesn't really make a lot of sense. */
623
624         if (selection)
625         {
626                 modest_address_book_add_address (selection);
627                 g_free (selection);
628         }
629 }
630
631 void
632 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
633 {
634         /* This is currently only implemented for Maemo */
635 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
636         if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
637                 modest_run_account_setup_wizard (win);
638                 return;
639         } else  {
640                 /* Show the list of accounts: */
641                 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
642                 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
643                 
644                 /* Don't make this a modal window, because secondary windows will then 
645                  * be unusable, freezing the UI: */
646                 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
647                 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win); 
648         }
649 #else
650         GtkWidget *dialog, *label;
651         
652         /* Create the widgets */
653         
654         dialog = gtk_dialog_new_with_buttons ("Message",
655                                               GTK_WINDOW(win),
656                                               GTK_DIALOG_DESTROY_WITH_PARENT,
657                                               GTK_STOCK_OK,
658                                               GTK_RESPONSE_NONE,
659                                               NULL);
660         label = gtk_label_new ("Hello World!");
661         
662         /* Ensure that the dialog box is destroyed when the user responds. */
663         
664         g_signal_connect_swapped (dialog, "response", 
665                                   G_CALLBACK (gtk_widget_destroy),
666                                   dialog);
667         
668         /* Add the label, and show everything we've added to the dialog. */
669         
670         gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
671                            label);
672         gtk_widget_show_all (dialog);
673 #endif /* MODEST_PLATFORM_MAEMO */
674 }
675
676 static void
677 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
678 {
679         /* Save any changes. */
680         modest_connection_specific_smtp_window_save_server_accounts (
681                         MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window));
682         gtk_widget_destroy (GTK_WIDGET (window));
683 }
684
685
686
687 void
688 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
689 {
690         /* This is currently only implemented for Maemo,
691          * because it requires an API (libconic) to detect different connection 
692          * possiblities.
693          */
694 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
695         
696         /* Create the window if necessary: */
697         GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
698         modest_connection_specific_smtp_window_fill_with_connections (
699                 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window), 
700                 modest_runtime_get_account_mgr());
701
702         /* Show the window: */  
703         gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
704         gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
705         gtk_widget_show (specific_window);
706     
707         /* Save changes when the window is hidden: */
708         g_signal_connect (specific_window, "hide", 
709                 G_CALLBACK (on_smtp_servers_window_hide), win);
710 #endif /* MODEST_PLATFORM_MAEMO */
711 }
712
713 void
714 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
715 {
716         ModestWindow *msg_win = NULL;
717         TnyMsg *msg = NULL;
718         TnyFolder *folder = NULL;
719         gchar *account_name = NULL;
720         gchar *from_str = NULL;
721 /*      GError *err = NULL; */
722         TnyAccount *account = NULL;
723         ModestWindowMgr *mgr;
724         gchar *signature = NULL, *blank_and_signature = NULL;
725
726         /* if there are no accounts yet, just show the wizard */
727         if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
728                         const gboolean created = modest_run_account_setup_wizard (win);
729                         if (!created)
730                                 return;
731         }
732         
733         account_name = g_strdup (modest_window_get_active_account (win));
734         if (!account_name)
735                 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
736         if (!account_name) {
737                 g_printerr ("modest: no account found\n");
738                 goto cleanup;
739         }
740         
741         account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
742                                                                        account_name,
743                                                                        TNY_ACCOUNT_TYPE_STORE);
744         if (!account) {
745                 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
746                 goto cleanup;
747         }
748
749         from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
750         if (!from_str) {
751                 g_printerr ("modest: failed get from string for '%s'\n", account_name);
752                 goto cleanup;
753         }
754
755         gboolean use_signature = FALSE;
756         signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
757
758         if (use_signature) {
759                 blank_and_signature = g_strconcat ("\n", signature, NULL);
760         } else {
761                 blank_and_signature = g_strdup ("");
762         }
763
764         g_free (signature);
765
766         msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
767         if (!msg) {
768                 g_printerr ("modest: failed to create new msg\n");
769                 goto cleanup;
770         }
771         
772         folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
773         if (!folder) {
774                 g_printerr ("modest: failed to find Drafts folder\n");
775                 goto cleanup;
776         }
777         
778         
779         /* Create and register edit window */
780         /* This is destroyed by TODO. */
781         msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
782         mgr = modest_runtime_get_window_mgr ();
783         modest_window_mgr_register_window (mgr, msg_win);
784
785         if (win)
786                 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
787                                               GTK_WINDOW (win));
788         gtk_widget_show_all (GTK_WIDGET (msg_win));
789
790 cleanup:
791         g_free (account_name);
792         g_free (from_str);
793         g_free (blank_and_signature);
794         if (msg_win)
795                 g_object_unref (msg_win);
796         if (account)
797                 g_object_unref (G_OBJECT(account));
798         if (msg)
799                 g_object_unref (G_OBJECT(msg));
800         if (folder)
801                 g_object_unref (G_OBJECT(folder));
802 }
803
804 gboolean 
805 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
806                                        TnyHeader *header,
807                                        TnyMsg *msg)
808 {
809         ModestMailOperationStatus status;
810
811         /* If there is no message or the operation was not successful */
812         status = modest_mail_operation_get_status (mail_op);
813         if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
814
815                 /* Remove the header from the preregistered uids */
816                 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),  
817                                                      header);
818
819                 return FALSE;
820         }
821
822         return TRUE;
823 }
824
825 static void
826 open_msg_cb (ModestMailOperation *mail_op, TnyHeader *header,  TnyMsg *msg, gpointer user_data)
827 {
828         ModestWindowMgr *mgr = NULL;
829         ModestWindow *parent_win = NULL;
830         ModestWindow *win = NULL;
831         TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
832         gchar *account = NULL;
833         TnyFolder *folder;
834         
835         /* Do nothing if there was any problem with the mail
836            operation. The error will be shown by the error_handler of
837            the mail operation */
838         if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
839                 return;
840
841         parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
842         folder = tny_header_get_folder (header);
843
844         /* Mark header as read */
845         headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
846
847         /* Get account */
848         account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
849         if (!account)
850                 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
851         
852         /* Gets folder type (OUTBOX headers will be opened in edit window */
853         if (modest_tny_folder_is_local_folder (folder))
854                 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
855
856         /* If the header is in the drafts folder then open the editor,
857            else the message view window */
858         if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
859             (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
860                 /* we cannot edit without a valid account... */
861                 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
862                         const gboolean created = modest_run_account_setup_wizard(parent_win);
863                         if (!created)
864                                 goto cleanup;
865                 }
866                 win = modest_msg_edit_window_new (msg, account, TRUE);
867
868
869                 /* Show banner */
870                 modest_platform_information_banner (NULL, NULL, _("mail_ib_opening_draft_message"));
871
872         } else {
873                 gchar *uid = modest_tny_folder_get_header_unique_id (header);
874                 
875                 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
876                         GtkWidget *header_view;
877                         GtkTreeSelection *sel;
878                         GList *sel_list = NULL;
879                         GtkTreeModel *model;
880                         
881                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
882                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
883
884                         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
885                         sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
886
887                         if (sel_list != NULL) {
888                                 GtkTreeRowReference *row_reference;
889
890                                 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
891                                 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
892                                 g_list_free (sel_list);
893                                 
894                                 win = modest_msg_view_window_new_with_header_model (
895                                                 msg, account, (const gchar*) uid,
896                                                 model, row_reference);
897                                 gtk_tree_row_reference_free (row_reference);
898                         } else {
899                                 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
900                         }
901                 } else {
902                         win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
903                 }
904                 g_free (uid);
905         }
906         
907         /* Register and show new window */
908         if (win != NULL) {
909                 mgr = modest_runtime_get_window_mgr ();
910                 modest_window_mgr_register_window (mgr, win);
911                 g_object_unref (win);
912                 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
913                 gtk_widget_show_all (GTK_WIDGET(win));
914         }
915
916         /* Update toolbar dimming state */
917         if (MODEST_IS_MAIN_WINDOW (parent_win)) {
918                 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
919         }
920
921 cleanup:
922         /* Free */
923         g_free(account);
924         g_object_unref (parent_win);
925         g_object_unref (folder);
926 }
927
928 void
929 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
930                                                gpointer user_data)
931 {
932         const GError *error;
933         GObject *win = modest_mail_operation_get_source (mail_op);
934
935         error = modest_mail_operation_get_error (mail_op);
936         printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
937  
938         if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
939
940                 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
941                                                         error->message);
942         } else {
943                 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
944                                                         _("mail_ni_ui_folder_get_msg_folder_error"));
945         }
946
947         if (win)
948                 g_object_unref (win);
949 }
950
951 /*
952  * This function is used by both modest_ui_actions_on_open and
953  * modest_ui_actions_on_header_activated. This way we always do the
954  * same when trying to open messages.
955  */
956 static void
957 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
958 {
959         ModestWindowMgr *mgr = NULL;
960         TnyIterator *iter = NULL;
961         ModestMailOperation *mail_op = NULL;
962         TnyList *not_opened_headers = NULL;
963         TnyHeaderFlags flags = 0;
964                 
965         g_return_if_fail (headers != NULL);
966
967         /* Check that only one message is selected for opening */
968         if (tny_list_get_length (headers) != 1) {
969                 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
970                                                         _("mcen_ib_select_one_message"));
971                 return;
972         }
973
974
975         /* Look if we already have a message view for each header. If
976            true, then remove the header from the list of headers to
977            open */
978         mgr = modest_runtime_get_window_mgr ();
979         iter = tny_list_create_iterator (headers);
980         not_opened_headers = tny_simple_list_new ();
981         
982         while (!tny_iterator_is_done (iter)) {
983
984                 ModestWindow *window = NULL;
985                 TnyHeader *header = NULL;
986                 gboolean found = FALSE;
987                 
988                 header = TNY_HEADER (tny_iterator_get_current (iter));
989                 if (header)
990                         flags = tny_header_get_flags (header);
991
992                 window = NULL;
993                 found = modest_window_mgr_find_registered_header (mgr, header, &window);
994                 
995                 /* Do not open again the message and present the
996                    window to the user */
997                 if (found) {
998                         if (window)
999                                 gtk_window_present (GTK_WINDOW (window));
1000                         else
1001                                 /* the header has been registered already, we don't do
1002                                  * anything but wait for the window to come up*/
1003                                 g_debug ("header %p already registered, waiting for window", header);
1004                 } else {
1005                         tny_list_append (not_opened_headers, G_OBJECT (header));
1006                 }
1007
1008                 if (header)
1009                         g_object_unref (header);
1010
1011                 tny_iterator_next (iter);
1012         }
1013         g_object_unref (iter);
1014         iter = NULL;
1015         
1016         /* If some messages would have to be downloaded, ask the user to 
1017          * make a connection. It's generally easier to do this here (in the mainloop) 
1018          * than later in a thread:
1019          */
1020         if (tny_list_get_length (not_opened_headers) > 0) {
1021                 TnyIterator *iter;
1022                 gboolean found = FALSE;
1023
1024                 iter = tny_list_create_iterator (not_opened_headers);
1025                 while (!tny_iterator_is_done (iter) && !found) {
1026                         TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1027                         if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1028                                 found = TRUE;
1029                         else
1030                                 tny_iterator_next (iter);
1031
1032                         g_object_unref (header);
1033                 }
1034                 g_object_unref (iter);
1035
1036                 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
1037                         g_object_unref (not_opened_headers);
1038                         return;                 
1039                 }
1040         }
1041         
1042         /* Register the headers before actually creating the windows: */
1043         TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
1044         while (!tny_iterator_is_done (iter_not_opened)) {
1045                 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1046                 if (header) {
1047                         modest_window_mgr_register_header (mgr, header);
1048                         g_object_unref (header);
1049                 }
1050                 
1051                 tny_iterator_next (iter_not_opened);
1052         }
1053         g_object_unref (iter_not_opened);
1054         iter_not_opened = NULL;
1055         
1056         /* Open each message */
1057         if (tny_list_get_length (not_opened_headers) > 0) {
1058                 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
1059                                                                          G_OBJECT (win), 
1060                                                                          modest_ui_actions_get_msgs_full_error_handler, 
1061                                                                          NULL);
1062                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1063                 if (tny_list_get_length (not_opened_headers) > 1) {
1064                         modest_mail_operation_get_msgs_full (mail_op, 
1065                                                              not_opened_headers, 
1066                                                              open_msg_cb, 
1067                                                              NULL, 
1068                                                              NULL);
1069                 } else {
1070                         TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1071                         TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1072                         modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1073                         g_object_unref (header);
1074                         g_object_unref (iter);
1075                 }
1076                 g_object_unref (mail_op);
1077         }
1078
1079         /* Clean */
1080         if (not_opened_headers != NULL)
1081                 g_object_unref (not_opened_headers);
1082 }
1083
1084 void
1085 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1086 {
1087         TnyList *headers;
1088
1089         /* Get headers */
1090         headers = get_selected_headers (win);
1091         if (!headers)
1092                 return;
1093
1094         /* Open them */
1095         _modest_ui_actions_open (headers, win);
1096
1097         g_object_unref(headers);
1098 }
1099
1100
1101 static void
1102 free_reply_forward_helper (gpointer data)
1103 {
1104         ReplyForwardHelper *helper;
1105
1106         helper = (ReplyForwardHelper *) data;
1107         g_free (helper->account_name);
1108         g_slice_free (ReplyForwardHelper, helper);
1109 }
1110
1111 static void
1112 reply_forward_cb (ModestMailOperation *mail_op,  TnyHeader *header, TnyMsg *msg,
1113                   gpointer user_data)
1114 {
1115         TnyMsg *new_msg;
1116         ReplyForwardHelper *rf_helper;
1117         ModestWindow *msg_win = NULL;
1118         ModestEditType edit_type;
1119         gchar *from = NULL;
1120         TnyAccount *account = NULL;
1121         ModestWindowMgr *mgr = NULL;
1122         gchar *signature = NULL;
1123
1124         /* If there was any error. The mail operation could be NULL,
1125            this means that we already have the message downloaded and
1126            that we didn't do a mail operation to retrieve it */
1127         if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1128                 return;
1129                         
1130         g_return_if_fail (user_data != NULL);
1131         rf_helper = (ReplyForwardHelper *) user_data;
1132
1133         from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1134                                                    rf_helper->account_name);
1135         if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1136                                          rf_helper->account_name,
1137                                          MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1138                 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1139                                                            rf_helper->account_name,
1140                                                            MODEST_ACCOUNT_SIGNATURE, FALSE);
1141         }
1142
1143         /* Create reply mail */
1144         switch (rf_helper->action) {
1145         case ACTION_REPLY:
1146                 new_msg = 
1147                         modest_tny_msg_create_reply_msg (msg, header, from, signature,
1148                                                          rf_helper->reply_forward_type,
1149                                                          MODEST_TNY_MSG_REPLY_MODE_SENDER);
1150                 break;
1151         case ACTION_REPLY_TO_ALL:
1152                 new_msg = 
1153                         modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1154                                                          MODEST_TNY_MSG_REPLY_MODE_ALL);
1155                 edit_type = MODEST_EDIT_TYPE_REPLY;
1156                 break;
1157         case ACTION_FORWARD:
1158                 new_msg = 
1159                         modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1160                 edit_type = MODEST_EDIT_TYPE_FORWARD;
1161                 break;
1162         default:
1163                 g_return_if_reached ();
1164                 return;
1165         }
1166
1167         g_free (signature);
1168
1169         if (!new_msg) {
1170                 g_printerr ("modest: failed to create message\n");
1171                 goto cleanup;
1172         }
1173
1174         account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1175                                                                        rf_helper->account_name,
1176                                                                        TNY_ACCOUNT_TYPE_STORE);
1177         if (!account) {
1178                 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1179                 goto cleanup;
1180         }
1181
1182         /* Create and register the windows */
1183         msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1184         mgr = modest_runtime_get_window_mgr ();
1185         modest_window_mgr_register_window (mgr, msg_win);
1186
1187         if (rf_helper->parent_window != NULL) {
1188                 gdouble parent_zoom;
1189
1190                 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1191                 modest_window_set_zoom (msg_win, parent_zoom);
1192         }
1193
1194         /* Show edit window */
1195         gtk_widget_show_all (GTK_WIDGET (msg_win));
1196
1197 cleanup:
1198         if (msg_win)
1199                 g_object_unref (msg_win);
1200         if (new_msg)
1201                 g_object_unref (G_OBJECT (new_msg));
1202         if (account)
1203                 g_object_unref (G_OBJECT (account));
1204 /*      g_object_unref (msg); */
1205         free_reply_forward_helper (rf_helper);
1206 }
1207
1208 /* Checks a list of headers. If any of them are not currently
1209  * downloaded (CACHED) then returns TRUE else returns FALSE.
1210  */
1211 static gint
1212 header_list_count_uncached_msgs (TnyList *header_list)
1213 {
1214         TnyIterator *iter;
1215         gint uncached_messages = 0;
1216
1217         iter = tny_list_create_iterator (header_list);
1218         while (!tny_iterator_is_done (iter)) {
1219                 TnyHeader *header;
1220
1221                 header = TNY_HEADER (tny_iterator_get_current (iter));
1222                 if (header) {
1223                         if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1224                                 uncached_messages ++;
1225                         g_object_unref (header);
1226                 }
1227
1228                 tny_iterator_next (iter);
1229         }
1230         g_object_unref (iter);
1231
1232         return uncached_messages;
1233 }
1234
1235 /* Returns FALSE if the user does not want to download the
1236  * messages. Returns TRUE if the user allowed the download.
1237  */
1238 static gboolean
1239 connect_to_get_msg (GtkWindow *win,
1240                     gint num_of_uncached_msgs)
1241 {
1242         /* Allways download if we are online. */
1243         if (tny_device_is_online (modest_runtime_get_device ()))
1244                 return TRUE;
1245
1246         /* If offline, then ask for user permission to download the messages */
1247         GtkResponseType response;
1248         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1249                         ngettext("mcen_nc_get_msg",
1250                         "mcen_nc_get_msgs",
1251                         num_of_uncached_msgs));
1252         if (response == GTK_RESPONSE_CANCEL)
1253                 return FALSE;
1254
1255         return modest_platform_connect_and_wait(win, NULL);     
1256 }
1257
1258 /*
1259  * Common code for the reply and forward actions
1260  */
1261 static void
1262 reply_forward (ReplyForwardAction action, ModestWindow *win)
1263 {
1264         ModestMailOperation *mail_op = NULL;
1265         TnyList *header_list = NULL;
1266         ReplyForwardHelper *rf_helper = NULL;
1267         guint reply_forward_type;
1268         gboolean continue_download = TRUE;
1269         gboolean do_retrieve = TRUE;
1270         
1271         g_return_if_fail (MODEST_IS_WINDOW(win));
1272
1273         /* we need an account when editing */
1274         if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1275                 const gboolean created = modest_run_account_setup_wizard (win);
1276                 if (!created)
1277                         return;
1278         }
1279         
1280         header_list = get_selected_headers (win);
1281         if (!header_list)
1282                 return;
1283
1284         reply_forward_type = 
1285                 modest_conf_get_int (modest_runtime_get_conf (),
1286                                      (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1287                                      NULL);
1288
1289         /* check if we need to download msg before asking about it */
1290         do_retrieve = (action == ACTION_FORWARD) ||
1291                         (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1292
1293         if (do_retrieve){
1294                 gint num_of_unc_msgs;
1295                 /* check that the messages have been previously downloaded */
1296                 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1297                 /* If there are any uncached message ask the user
1298                  * whether he/she wants to download them. */
1299                 if (num_of_unc_msgs)
1300                         continue_download = connect_to_get_msg (
1301                                                                 GTK_WINDOW (win),
1302                                                                 num_of_unc_msgs);
1303         }
1304
1305         if (!continue_download) {
1306                 g_object_unref (header_list);
1307                 return;
1308         }
1309         
1310         /* We assume that we can only select messages of the
1311            same folder and that we reply all of them from the
1312            same account. In fact the interface currently only
1313            allows single selection */
1314         
1315         /* Fill helpers */
1316         rf_helper = g_slice_new0 (ReplyForwardHelper);
1317         rf_helper->reply_forward_type = reply_forward_type;
1318         rf_helper->action = action;
1319         rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1320         
1321         if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1322                 rf_helper->parent_window = GTK_WIDGET (win);
1323         if (!rf_helper->account_name)
1324                 rf_helper->account_name =
1325                         modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1326
1327         if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1328                 TnyMsg *msg;
1329                 TnyHeader *header;
1330                 /* Get header and message. Do not free them here, the
1331                    reply_forward_cb must do it */
1332                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1333                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1334                 if (!msg || !header) {
1335                         if (msg)
1336                                 g_object_unref (msg);
1337                         g_printerr ("modest: no message found\n");
1338                         return;
1339                 } else {
1340                         reply_forward_cb (NULL, header, msg, rf_helper);
1341                 }
1342                 if (header)
1343                         g_object_unref (header);
1344         } else {
1345                 TnyHeader *header;
1346                 TnyIterator *iter;
1347
1348                 /* Only reply/forward to one message */
1349                 iter = tny_list_create_iterator (header_list);
1350                 header = TNY_HEADER (tny_iterator_get_current (iter));
1351                 g_object_unref (iter);
1352
1353                 if (header) {
1354                         /* Retrieve messages */
1355                         if (do_retrieve) {
1356                                 mail_op = modest_mail_operation_new_with_error_handling (
1357                                         MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
1358                                         G_OBJECT(win),
1359                                         modest_ui_actions_get_msgs_full_error_handler, 
1360                                         NULL);
1361                                 modest_mail_operation_queue_add (
1362                                         modest_runtime_get_mail_operation_queue (), mail_op);
1363                                 
1364                                 modest_mail_operation_get_msg (mail_op,
1365                                                                header,
1366                                                                reply_forward_cb,
1367                                                                rf_helper);
1368                                 /* Clean */
1369                                 g_object_unref(mail_op);
1370                         } else {
1371                                 /* we put a ref here to prevent double unref as the reply
1372                                  * forward callback unrefs the header at its end */
1373                                 reply_forward_cb (NULL, header, NULL, rf_helper);
1374                         }
1375
1376
1377                         g_object_unref (header);
1378                 }
1379
1380         }
1381
1382         /* Free */
1383         g_object_unref (header_list);
1384 }
1385
1386 void
1387 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1388 {
1389         g_return_if_fail (MODEST_IS_WINDOW(win));
1390
1391         reply_forward (ACTION_REPLY, win);
1392 }
1393
1394 void
1395 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1396 {
1397         g_return_if_fail (MODEST_IS_WINDOW(win));
1398
1399         reply_forward (ACTION_FORWARD, win);
1400 }
1401
1402 void
1403 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1404 {
1405         g_return_if_fail (MODEST_IS_WINDOW(win));
1406
1407         reply_forward (ACTION_REPLY_TO_ALL, win);
1408 }
1409
1410 void 
1411 modest_ui_actions_on_next (GtkAction *action, 
1412                            ModestWindow *window)
1413 {
1414         if (MODEST_IS_MAIN_WINDOW (window)) {
1415                 GtkWidget *header_view;
1416
1417                 header_view = modest_main_window_get_child_widget (
1418                                 MODEST_MAIN_WINDOW(window),
1419                                 MODEST_WIDGET_TYPE_HEADER_VIEW);
1420                 if (!header_view)
1421                         return;
1422         
1423                 modest_header_view_select_next (
1424                                 MODEST_HEADER_VIEW(header_view)); 
1425         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1426                 modest_msg_view_window_select_next_message (
1427                                 MODEST_MSG_VIEW_WINDOW (window));
1428         } else {
1429                 g_return_if_reached ();
1430         }
1431 }
1432
1433 void 
1434 modest_ui_actions_on_prev (GtkAction *action, 
1435                            ModestWindow *window)
1436 {
1437         g_return_if_fail (MODEST_IS_WINDOW(window));
1438
1439         if (MODEST_IS_MAIN_WINDOW (window)) {
1440                 GtkWidget *header_view;
1441                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1442                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
1443                 if (!header_view)
1444                         return;
1445                 
1446                 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view)); 
1447         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1448                 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1449         } else {
1450                 g_return_if_reached ();
1451         }
1452 }
1453
1454 void 
1455 modest_ui_actions_on_sort (GtkAction *action, 
1456                            ModestWindow *window)
1457 {
1458         g_return_if_fail (MODEST_IS_WINDOW(window));
1459
1460         if (MODEST_IS_MAIN_WINDOW (window)) {
1461                 GtkWidget *header_view;
1462                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1463                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
1464                 if (!header_view) {
1465                         modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1466
1467                         return;
1468                 }
1469
1470                 /* Show sorting dialog */
1471                 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);     
1472         }
1473 }
1474
1475 static void
1476 new_messages_arrived (ModestMailOperation *self, 
1477                       gint new_messages,
1478                       gpointer user_data)
1479 {
1480         ModestMainWindow *win = NULL;
1481         GtkWidget *folder_view = NULL;
1482         TnyFolderStore *folder = NULL;
1483         gboolean folder_empty = FALSE;
1484
1485         g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1486         win = MODEST_MAIN_WINDOW (user_data);
1487
1488         /* Set contents style of headers view */
1489         if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1490                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win), 
1491                                                                    MODEST_WIDGET_TYPE_FOLDER_VIEW);
1492                 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));             
1493                 
1494
1495                 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1496                 
1497                 if (!folder_empty)
1498                         modest_main_window_set_contents_style (win,
1499                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1500         }       
1501
1502         /* Notify new messages have been downloaded */
1503         if (new_messages > 0)
1504                 modest_platform_on_new_msg ();
1505 }
1506
1507 /*
1508  * This function performs the send & receive required actions. The
1509  * window is used to create the mail operation. Typically it should
1510  * always be the main window, but we pass it as argument in order to
1511  * be more flexible.
1512  */
1513 void
1514 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1515 {
1516         gchar *acc_name = NULL;
1517         ModestMailOperation *mail_op;
1518
1519         /* If no account name was provided then get the current account, and if
1520            there is no current account then pick the default one: */
1521         if (!account_name) {
1522                 acc_name = g_strdup (modest_window_get_active_account(win));
1523                 if (!acc_name)
1524                         acc_name  = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1525                 if (!acc_name) {
1526                         g_printerr ("modest: cannot get default account\n");
1527                         return;
1528                 }
1529         } else {
1530                 acc_name = g_strdup (account_name);
1531         }
1532
1533         /* Set send/receive operation in progress */    
1534         modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1535
1536         mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1537                                                                  G_OBJECT (win),
1538                                                                  modest_ui_actions_send_receive_error_handler,
1539                                                                  NULL);
1540
1541         g_signal_connect (G_OBJECT(mail_op), "progress-changed", 
1542                           G_CALLBACK (_on_send_receive_progress_changed), 
1543                           win);
1544
1545         /* Send & receive. */
1546         /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1547         /* Receive and then send. The operation is tagged initially as
1548            a receive operation because the account update performs a
1549            receive and then a send. The operation changes its type
1550            internally, so the progress objects will receive the proper
1551            progress information */
1552         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1553         modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1554         g_object_unref (G_OBJECT (mail_op));
1555         
1556         /* Free */
1557         g_free (acc_name);
1558 }
1559
1560
1561 static void
1562 modest_ui_actions_do_cancel_send (const gchar *account_name,  
1563                                   ModestWindow *win)
1564 {
1565         TnyTransportAccount *transport_account;
1566         TnySendQueue *send_queue = NULL;
1567         GError *error = NULL;
1568
1569         /* Get transport account */
1570         transport_account =
1571                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1572                                       (modest_runtime_get_account_store(),
1573                                        account_name,
1574                                        TNY_ACCOUNT_TYPE_TRANSPORT));
1575         if (!transport_account) {
1576                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1577                 goto frees;
1578         }
1579
1580         /* Get send queue*/
1581         send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1582         if (!TNY_IS_SEND_QUEUE(send_queue)) {
1583                 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1584                              MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1585                              "modest: could not find send queue for account\n");
1586         } else {
1587                 /* Keeep messages in outbox folder */
1588                 tny_send_queue_cancel (send_queue, FALSE, &error);
1589         }       
1590
1591  frees:
1592         if (transport_account != NULL) 
1593                 g_object_unref (G_OBJECT (transport_account));
1594 }
1595
1596 static void
1597 modest_ui_actions_cancel_send_all (ModestWindow *win) 
1598 {
1599         GSList *account_names, *iter;
1600
1601         account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), 
1602                                                           TRUE);
1603
1604         iter = account_names;
1605         while (iter) {                  
1606                 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1607                 iter = g_slist_next (iter);
1608         }
1609
1610         modest_account_mgr_free_account_names (account_names);
1611         account_names = NULL;
1612 }
1613
1614 void
1615 modest_ui_actions_cancel_send (GtkAction *action,  ModestWindow *win)
1616
1617 {
1618         /* Check if accounts exist */
1619         gboolean accounts_exist = 
1620                 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1621         
1622         /* If not, allow the user to create an account before trying to send/receive. */
1623         if (!accounts_exist)
1624                 modest_ui_actions_on_accounts (NULL, win);
1625         
1626         /* Cancel all sending operaitons */     
1627         modest_ui_actions_cancel_send_all (win);
1628 }
1629
1630 /*
1631  * Refreshes all accounts. This function will be used by automatic
1632  * updates
1633  */
1634 void
1635 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1636 {
1637         GSList *account_names, *iter;
1638
1639         account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), 
1640                                                           TRUE);
1641
1642         iter = account_names;
1643         while (iter) {                  
1644                 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1645                 iter = g_slist_next (iter);
1646         }
1647
1648         modest_account_mgr_free_account_names (account_names);
1649         account_names = NULL;
1650 }
1651
1652 void 
1653 modest_do_refresh_current_folder(ModestWindow *win)
1654 {
1655         /* Refresh currently selected folder. Note that if we only
1656            want to retreive the headers, then the refresh only will
1657            invoke a poke_status over all folders, i.e., only the
1658            total/unread count will be updated */
1659         if (MODEST_IS_MAIN_WINDOW (win)) {
1660                 GtkWidget *header_view, *folder_view;
1661                 TnyFolderStore *folder_store;
1662
1663                 /* Get folder and header view */
1664                 folder_view = 
1665                         modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win), 
1666                                                              MODEST_WIDGET_TYPE_FOLDER_VIEW);
1667                 if (!folder_view)
1668                         return;
1669
1670                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1671
1672                 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1673                         header_view = 
1674                                 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1675                                                                      MODEST_WIDGET_TYPE_HEADER_VIEW);
1676                 
1677                         /* We do not need to set the contents style
1678                            because it hasn't changed. We also do not
1679                            need to save the widget status. Just force
1680                            a refresh */
1681                         modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1682                                                        TNY_FOLDER (folder_store),
1683                                                        folder_refreshed_cb,
1684                                                        MODEST_MAIN_WINDOW (win));
1685                 }
1686                 
1687                 if (folder_store)
1688                         g_object_unref (folder_store);
1689         }
1690 }
1691
1692
1693 /*
1694  * Handler of the click on Send&Receive button in the main toolbar
1695  */
1696 void
1697 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1698 {
1699         /* Check if accounts exist */
1700         gboolean accounts_exist = 
1701                 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1702         
1703         /* If not, allow the user to create an account before trying to send/receive. */
1704         if (!accounts_exist)
1705                 modest_ui_actions_on_accounts (NULL, win);
1706
1707         modest_do_refresh_current_folder (win);
1708         
1709         /* Refresh the active account */
1710         modest_ui_actions_do_send_receive (NULL, win);
1711 }
1712
1713
1714 void
1715 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1716 {
1717         ModestConf *conf;
1718         GtkWidget *header_view;
1719         
1720         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1721
1722         header_view = modest_main_window_get_child_widget (main_window,
1723                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
1724         if (!header_view)
1725                 return;
1726
1727         conf = modest_runtime_get_conf ();
1728         
1729         /* what is saved/restored is depending on the style; thus; we save with
1730          * old style, then update the style, and restore for this new style
1731          */
1732         modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1733         
1734         if (modest_header_view_get_style
1735             (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1736                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1737                                               MODEST_HEADER_VIEW_STYLE_TWOLINES);
1738         else
1739                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1740                                               MODEST_HEADER_VIEW_STYLE_DETAILS);
1741
1742         modest_widget_memory_restore (conf, G_OBJECT(header_view),
1743                                       MODEST_CONF_HEADER_VIEW_KEY);
1744 }
1745
1746
1747 void 
1748 modest_ui_actions_on_header_selected (ModestHeaderView *header_view, 
1749                                       TnyHeader *header,
1750                                       ModestMainWindow *main_window)
1751 {
1752         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1753         g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1754         
1755         /* in the case the folder is empty, show the empty folder message and focus
1756          * folder view */
1757         if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1758                 if (modest_header_view_is_empty (header_view)) {
1759                         TnyFolder *folder = modest_header_view_get_folder (header_view);
1760                         GtkWidget *folder_view = 
1761                                 modest_main_window_get_child_widget (main_window,
1762                                                                      MODEST_WIDGET_TYPE_FOLDER_VIEW);
1763                         if (folder != NULL) 
1764                                 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1765                         gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1766                         return;
1767                 }
1768         }
1769         /* If no header has been selected then exit */
1770         if (!header)
1771                 return;
1772
1773         /* Update focus */
1774         if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1775             gtk_widget_grab_focus (GTK_WIDGET(header_view));
1776
1777         /* Update toolbar dimming state */
1778         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1779 }
1780
1781 void
1782 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1783                                        TnyHeader *header,
1784                                        ModestMainWindow *main_window)
1785 {
1786         TnyList *headers;
1787
1788         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1789         
1790         if (!header)
1791                 return;
1792
1793
1794 /*      headers = tny_simple_list_new (); */
1795 /*      tny_list_prepend (headers, G_OBJECT (header)); */
1796         headers = modest_header_view_get_selected_headers (header_view);
1797
1798         _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1799
1800         g_object_unref (headers);
1801 }
1802
1803 static void
1804 set_active_account_from_tny_account (TnyAccount *account,
1805                                      ModestWindow *window)
1806 {
1807         const gchar *server_acc_name = tny_account_get_id (account);
1808         
1809         /* We need the TnyAccount provided by the
1810            account store because that is the one that
1811            knows the name of the Modest account */
1812         TnyAccount *modest_server_account = modest_server_account = 
1813                 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1814                                                              MODEST_TNY_ACCOUNT_STORE_QUERY_ID, 
1815                                                              server_acc_name);
1816         if (!modest_server_account) {
1817                 g_warning ("%s: could not get tny account\n", __FUNCTION__);
1818                 return;
1819         }
1820
1821         /* Update active account, but only if it's not a pseudo-account */
1822         if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
1823             (!modest_tny_account_is_memory_card_account(modest_server_account))) {
1824                 const gchar *modest_acc_name = 
1825                         modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1826                 if (modest_acc_name)
1827                         modest_window_set_active_account (window, modest_acc_name);
1828         }
1829         
1830         g_object_unref (modest_server_account);
1831 }
1832
1833
1834 static void
1835 folder_refreshed_cb (ModestMailOperation *mail_op, 
1836                      TnyFolder *folder, 
1837                      gpointer user_data)
1838 {
1839         ModestMainWindow *win = NULL;
1840         GtkWidget *header_view;
1841         gboolean folder_empty = FALSE;
1842         gboolean all_marked_as_deleted = FALSE;
1843
1844         g_return_if_fail (TNY_IS_FOLDER (folder));
1845
1846         win = MODEST_MAIN_WINDOW (user_data);
1847         header_view = 
1848                 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1849
1850         if (header_view) {
1851                 TnyFolder *current_folder;
1852
1853                 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1854                 if (current_folder != NULL && folder != current_folder) {
1855                         g_object_unref (current_folder);
1856                         return;
1857                 }
1858                 g_object_unref (current_folder);
1859         }
1860
1861         /* Check if folder is empty and set headers view contents style */
1862         folder_empty = (tny_folder_get_all_count (folder) == 0);
1863         all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1864         if (folder_empty || all_marked_as_deleted)
1865                 modest_main_window_set_contents_style (win,
1866                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1867 }
1868
1869 void 
1870 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1871                                                TnyFolderStore *folder_store, 
1872                                                gboolean selected,
1873                                                ModestMainWindow *main_window)
1874 {
1875         ModestConf *conf;
1876         GtkWidget *header_view;
1877
1878         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1879
1880         header_view = modest_main_window_get_child_widget(main_window,
1881                                                           MODEST_WIDGET_TYPE_HEADER_VIEW);
1882         if (!header_view)
1883                 return;
1884         
1885         conf = modest_runtime_get_conf ();
1886
1887         if (TNY_IS_ACCOUNT (folder_store)) {
1888                 if (selected) {
1889                         set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1890                         
1891                         /* Show account details */
1892                         modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1893                 }
1894         } else {
1895                 if (TNY_IS_FOLDER (folder_store) && selected) {
1896                         
1897                         /* Update the active account */
1898                         TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1899                         if (account) {
1900                                 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1901                                 g_object_unref (account);
1902                                 account = NULL;
1903                         }
1904
1905                         /* Set the header style by default, it could
1906                            be changed later by the refresh callback to
1907                            empty */
1908                         modest_main_window_set_contents_style (main_window, 
1909                                                                MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1910
1911                         /* Set folder on header view. This function
1912                            will call tny_folder_refresh_async so we
1913                            pass a callback that will be called when
1914                            finished. We use that callback to set the
1915                            empty view if there are no messages */
1916                         modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1917                                                        TNY_FOLDER (folder_store),
1918                                                        folder_refreshed_cb,
1919                                                        main_window);
1920                         
1921                         /* Restore configuration. We need to do this
1922                            *after* the set_folder because the widget
1923                            memory asks the header view about its
1924                            folder  */
1925                         modest_widget_memory_restore (modest_runtime_get_conf (), 
1926                                                       G_OBJECT(header_view),
1927                                                       MODEST_CONF_HEADER_VIEW_KEY);
1928                 } else {
1929                         /* Update the active account */
1930                         //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1931                         /* Save only if we're seeing headers */
1932                         if (modest_main_window_get_contents_style (main_window) ==
1933                             MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1934                                 modest_widget_memory_save (conf, G_OBJECT (header_view), 
1935                                                            MODEST_CONF_HEADER_VIEW_KEY);
1936                         modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1937                 }
1938         }
1939
1940         /* Update toolbar dimming state */
1941         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1942 }
1943
1944 void 
1945 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1946                                      ModestWindow *win)
1947 {
1948         GtkWidget *dialog;
1949         gchar *txt, *item;
1950         gboolean online;
1951
1952         item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1953         
1954         online = tny_device_is_online (modest_runtime_get_device());
1955
1956         if (online) {
1957                 /* already online -- the item is simply not there... */
1958                 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1959                                                  GTK_DIALOG_MODAL,
1960                                                  GTK_MESSAGE_WARNING,
1961                                                  GTK_BUTTONS_NONE,
1962                                                  _("The %s you selected cannot be found"),
1963                                                  item);
1964                 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
1965                 gtk_dialog_run (GTK_DIALOG(dialog));
1966         } else {
1967                 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1968                                                       GTK_WINDOW (win),
1969                                                       GTK_DIALOG_MODAL,
1970                                                       _("mcen_bd_dialog_cancel"),
1971                                                       GTK_RESPONSE_REJECT,
1972                                                       _("mcen_bd_dialog_ok"),
1973                                                       GTK_RESPONSE_ACCEPT,
1974                                                       NULL);
1975                 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1976                                          "Do you want to get online?"), item);
1977                 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1978                                     gtk_label_new (txt), FALSE, FALSE, 0);
1979                 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1980                 g_free (txt);
1981
1982                 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1983                 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1984                         /* TODO: Comment about why is this commented out: */
1985                         /* modest_platform_connect_and_wait (); */
1986                 }
1987         }
1988         gtk_widget_destroy (dialog);
1989 }
1990
1991 void
1992 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1993                                      ModestWindow *win)
1994 {
1995         /* g_message ("%s %s", __FUNCTION__, link); */
1996 }       
1997
1998
1999 void
2000 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2001                                         ModestWindow *win)
2002 {
2003         modest_platform_activate_uri (link);
2004 }
2005
2006 void
2007 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2008                                           ModestWindow *win)
2009 {
2010         modest_platform_show_uri_popup (link);
2011 }
2012
2013 void
2014 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2015                                              ModestWindow *win)
2016 {
2017         modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2018 }
2019
2020 void
2021 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2022                                           const gchar *address,
2023                                           ModestWindow *win)
2024 {
2025         /* g_message ("%s %s", __FUNCTION__, address); */
2026 }
2027
2028 void
2029 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2030 {
2031         TnyTransportAccount *transport_account;
2032         ModestMailOperation *mail_operation;
2033         MsgData *data;
2034         gchar *account_name, *from;
2035         ModestAccountMgr *account_mgr;
2036         gchar *info_text = NULL;
2037
2038         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2039         
2040         data = modest_msg_edit_window_get_msg_data (edit_window);
2041
2042         account_mgr = modest_runtime_get_account_mgr();
2043         account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2044         if (!account_name) 
2045                 account_name = modest_account_mgr_get_default_account (account_mgr);
2046         if (!account_name) {
2047                 g_printerr ("modest: no account found\n");
2048                 modest_msg_edit_window_free_msg_data (edit_window, data);
2049                 return;
2050         }
2051
2052         if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2053                 account_name = g_strdup (data->account_name);
2054         }
2055
2056         transport_account =
2057                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2058                                       (modest_runtime_get_account_store(),
2059                                        account_name,
2060                                        TNY_ACCOUNT_TYPE_TRANSPORT));
2061         if (!transport_account) {
2062                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2063                 g_free (account_name);
2064                 modest_msg_edit_window_free_msg_data (edit_window, data);
2065                 return;
2066         }
2067         from = modest_account_mgr_get_from_string (account_mgr, account_name);
2068
2069         /* Create the mail operation */         
2070         mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2071         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2072
2073         modest_mail_operation_save_to_drafts (mail_operation,
2074                                               transport_account,
2075                                               data->draft_msg,
2076                                               edit_window,
2077                                               from,
2078                                               data->to, 
2079                                               data->cc, 
2080                                               data->bcc,
2081                                               data->subject, 
2082                                               data->plain_body, 
2083                                               data->html_body,
2084                                               data->attachments,
2085                                               data->priority_flags);
2086         /* Frees */
2087         g_free (from);
2088         g_free (account_name);
2089         g_object_unref (G_OBJECT (transport_account));
2090         g_object_unref (G_OBJECT (mail_operation));
2091
2092         modest_msg_edit_window_free_msg_data (edit_window, data);
2093
2094         info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2095         modest_platform_information_banner (NULL, NULL, info_text);
2096         g_free (info_text);
2097 }
2098
2099 /* For instance, when clicking the Send toolbar button when editing a message: */
2100 void
2101 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2102 {
2103         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2104
2105         if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2106                 return;
2107         
2108         /* Offer the connection dialog, if necessary: */        
2109         if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2110                 return;
2111         
2112         /* FIXME: Code added just for testing. The final version will
2113            use the send queue provided by tinymail and some
2114            classifier */
2115         ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2116         gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2117         if (!account_name) 
2118                 account_name = modest_account_mgr_get_default_account (account_mgr);
2119                 
2120         if (!account_name) {
2121                 /* Run account setup wizard */
2122                 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2123                 if (!created)
2124                         return;
2125         }
2126         
2127         MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2128
2129         if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2130                 account_name = g_strdup (data->account_name);
2131         }
2132         
2133         /* Get the currently-active transport account for this modest account: */
2134         TnyTransportAccount *transport_account =
2135                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2136                                       (modest_runtime_get_account_store(),
2137                                        account_name));
2138         if (!transport_account) {
2139                 /* Run account setup wizard */
2140                 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2141                 if (!created)
2142                         return;
2143         }
2144         
2145         gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2146
2147         /* Create the mail operation */
2148         ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2149         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2150
2151         modest_mail_operation_send_new_mail (mail_operation,
2152                                              transport_account,
2153                                              data->draft_msg,
2154                                              from,
2155                                              data->to, 
2156                                              data->cc, 
2157                                              data->bcc,
2158                                              data->subject, 
2159                                              data->plain_body, 
2160                                              data->html_body,
2161                                              data->attachments,
2162                                              data->priority_flags);
2163                                              
2164         /* Free data: */
2165         g_free (from);
2166         g_free (account_name);
2167         g_object_unref (G_OBJECT (transport_account));
2168         g_object_unref (G_OBJECT (mail_operation));
2169
2170         modest_msg_edit_window_free_msg_data (edit_window, data);
2171         modest_msg_edit_window_set_sent (edit_window, TRUE);
2172
2173         /* Save settings and close the window: */
2174         modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2175 }
2176
2177 void 
2178 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2179                                   ModestMsgEditWindow *window)
2180 {
2181         ModestMsgEditFormatState *format_state = NULL;
2182
2183         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2184         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2185
2186         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2187                 return;
2188
2189         format_state = modest_msg_edit_window_get_format_state (window);
2190         g_return_if_fail (format_state != NULL);
2191
2192         format_state->bold = gtk_toggle_action_get_active (action);
2193         modest_msg_edit_window_set_format_state (window, format_state);
2194         g_free (format_state);
2195         
2196 }
2197
2198 void 
2199 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2200                                      ModestMsgEditWindow *window)
2201 {
2202         ModestMsgEditFormatState *format_state = NULL;
2203
2204         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2205         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2206
2207         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2208                 return;
2209
2210         format_state = modest_msg_edit_window_get_format_state (window);
2211         g_return_if_fail (format_state != NULL);
2212
2213         format_state->italics = gtk_toggle_action_get_active (action);
2214         modest_msg_edit_window_set_format_state (window, format_state);
2215         g_free (format_state);
2216         
2217 }
2218
2219 void 
2220 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2221                                      ModestMsgEditWindow *window)
2222 {
2223         ModestMsgEditFormatState *format_state = NULL;
2224
2225         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2226         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2227
2228         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2229                 return;
2230
2231         format_state = modest_msg_edit_window_get_format_state (window);
2232         g_return_if_fail (format_state != NULL);
2233
2234         format_state->bullet = gtk_toggle_action_get_active (action);
2235         modest_msg_edit_window_set_format_state (window, format_state);
2236         g_free (format_state);
2237         
2238 }
2239
2240 void 
2241 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2242                                      GtkRadioAction *selected,
2243                                      ModestMsgEditWindow *window)
2244 {
2245         ModestMsgEditFormatState *format_state = NULL;
2246         GtkJustification value;
2247
2248         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2249
2250         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2251                 return;
2252
2253         value = gtk_radio_action_get_current_value (selected);
2254
2255         format_state = modest_msg_edit_window_get_format_state (window);
2256         g_return_if_fail (format_state != NULL);
2257
2258         format_state->justification = value;
2259         modest_msg_edit_window_set_format_state (window, format_state);
2260         g_free (format_state);
2261 }
2262
2263 void 
2264 modest_ui_actions_on_select_editor_color (GtkAction *action,
2265                                           ModestMsgEditWindow *window)
2266 {
2267         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2268         g_return_if_fail (GTK_IS_ACTION (action));
2269
2270         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2271                 return;
2272
2273         modest_msg_edit_window_select_color (window);
2274 }
2275
2276 void 
2277 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2278                                                      ModestMsgEditWindow *window)
2279 {
2280         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2281         g_return_if_fail (GTK_IS_ACTION (action));
2282
2283         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2284                 return;
2285
2286         modest_msg_edit_window_select_background_color (window);
2287 }
2288
2289 void 
2290 modest_ui_actions_on_insert_image (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         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2297                 return;
2298
2299         modest_msg_edit_window_insert_image (window);
2300 }
2301
2302 void 
2303 modest_ui_actions_on_attach_file (GtkAction *action,
2304                                   ModestMsgEditWindow *window)
2305 {
2306         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2307         g_return_if_fail (GTK_IS_ACTION (action));
2308
2309         modest_msg_edit_window_offer_attach_file (window);
2310 }
2311
2312 void 
2313 modest_ui_actions_on_remove_attachments (GtkAction *action,
2314                                          ModestMsgEditWindow *window)
2315 {
2316         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2317         g_return_if_fail (GTK_IS_ACTION (action));
2318
2319         modest_msg_edit_window_remove_attachments (window, NULL);
2320 }
2321
2322 static void
2323 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2324                                             gpointer user_data)
2325 {
2326         ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2327         const GError *error = modest_mail_operation_get_error (mail_op);
2328
2329         if(error)
2330         {
2331                 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2332                                                     modest_mail_operation_get_error (mail_op)->message);
2333         }
2334 }
2335
2336 static void
2337 modest_ui_actions_create_folder(GtkWidget *parent_window,
2338                                 GtkWidget *folder_view)
2339 {
2340         TnyFolderStore *parent_folder;
2341
2342         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2343         
2344         if (parent_folder) {
2345                 gboolean finished = FALSE;
2346                 gint result;
2347                 gchar *folder_name = NULL, *suggested_name = NULL;
2348                 const gchar *proto_str = NULL;
2349                 TnyAccount *account;
2350
2351                 if (TNY_IS_ACCOUNT (parent_folder))
2352                         account = g_object_ref (parent_folder);
2353                 else
2354                         account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2355                 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2356
2357                 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2358                     MODEST_PROTOCOL_STORE_POP) {
2359                         finished = TRUE;
2360                         hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2361                 }
2362                 g_object_unref (account);
2363
2364                 /* Run the new folder dialog */
2365                 while (!finished) {
2366                         result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2367                                                                         parent_folder,
2368                                                                         suggested_name,
2369                                                                         &folder_name);
2370
2371                         g_free (suggested_name);
2372                         suggested_name = NULL;
2373
2374                         if (result == GTK_RESPONSE_REJECT) {
2375                                 finished = TRUE;
2376                         } else {
2377                                 ModestMailOperation *mail_op;
2378                                 TnyFolder *new_folder = NULL;
2379
2380                                 mail_op  = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2381                                                                                           G_OBJECT(parent_window),
2382                                                                                           modest_ui_actions_new_folder_error_handler,
2383                                                                                           parent_window);
2384
2385                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
2386                                                                  mail_op);
2387                                 new_folder = modest_mail_operation_create_folder (mail_op,
2388                                                                                   parent_folder,
2389                                                                                   (const gchar *) folder_name);
2390                                 if (new_folder) {
2391                                         modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), 
2392                                                                           new_folder, TRUE);
2393
2394                                         g_object_unref (new_folder);
2395                                         finished = TRUE;
2396                                 }
2397                                 g_object_unref (mail_op);
2398                         }
2399
2400                         suggested_name = folder_name;
2401                         folder_name = NULL;
2402                 }
2403
2404                 g_object_unref (parent_folder);
2405         }
2406 }
2407
2408 void 
2409 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2410 {
2411         GtkWidget *folder_view;
2412         
2413         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2414
2415         folder_view = modest_main_window_get_child_widget (main_window,
2416                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2417         if (!folder_view)
2418                 return;
2419
2420         modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2421 }
2422
2423 static void
2424 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2425                                                gpointer user_data)
2426 {
2427         ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2428         const GError *error = NULL;
2429         const gchar *message = NULL;
2430         
2431         /* Get error message */
2432         error = modest_mail_operation_get_error (mail_op);
2433         if (!error)
2434                 g_return_if_reached ();
2435
2436         switch (error->code) {
2437         case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2438                 message = _CS("ckdg_ib_folder_already_exists");
2439                 break;
2440         default:
2441                 g_return_if_reached ();
2442         }
2443
2444         modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2445 }
2446
2447 void 
2448 modest_ui_actions_on_rename_folder (GtkAction *action,
2449                                      ModestMainWindow *main_window)
2450 {
2451         TnyFolderStore *folder;
2452         GtkWidget *folder_view;
2453         GtkWidget *header_view; 
2454
2455         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2456
2457         folder_view = modest_main_window_get_child_widget (main_window,
2458                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2459         if (!folder_view)
2460                 return;
2461
2462         header_view = modest_main_window_get_child_widget (main_window,
2463                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
2464         
2465         if (!header_view)
2466                 return;
2467
2468         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2469
2470         if (!folder)
2471                 return;
2472
2473         if (TNY_IS_FOLDER (folder)) {
2474                 gchar *folder_name;
2475                 gint response;
2476                 const gchar *current_name;
2477                 TnyFolderStore *parent;
2478                 gboolean do_rename = TRUE;
2479
2480                 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2481                 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2482                 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), 
2483                                                                      parent, current_name, 
2484                                                                      &folder_name);
2485                 g_object_unref (parent);
2486
2487                 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2488                         do_rename = FALSE;
2489                 } else if (modest_platform_is_network_folderstore(folder) &&
2490                            !tny_device_is_online (modest_runtime_get_device())) {
2491                         TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2492                         do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2493                         g_object_unref(account);
2494                 }
2495
2496                 if (do_rename) {
2497                         ModestMailOperation *mail_op;
2498                         GtkTreeSelection *sel = NULL;
2499
2500                         mail_op = 
2501                                 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2502                                                                                G_OBJECT(main_window),
2503                                                                                modest_ui_actions_rename_folder_error_handler,
2504                                                                                main_window);
2505
2506                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2507                                                          mail_op);
2508
2509                         /* Clear the headers view */
2510                         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2511                         gtk_tree_selection_unselect_all (sel);
2512
2513                         /* Select *after* the changes */
2514                         modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2515                                                           TNY_FOLDER(folder), TRUE);
2516
2517                         /* Actually rename the folder */
2518                         modest_mail_operation_rename_folder (mail_op,
2519                                                              TNY_FOLDER (folder),
2520                                                              (const gchar *) folder_name);
2521
2522                         g_object_unref (mail_op);
2523                         g_free (folder_name);
2524                 }
2525         }
2526         g_object_unref (folder);
2527 }
2528
2529 static void
2530 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2531                                                gpointer user_data)
2532 {
2533         GObject *win = modest_mail_operation_get_source (mail_op);
2534
2535         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2536                                                 _("mail_in_ui_folder_delete_error"));
2537         g_object_unref (win);
2538 }
2539
2540 static void
2541 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash) 
2542 {
2543         TnyFolderStore *folder;
2544         GtkWidget *folder_view;
2545         gint response;
2546         gchar *message;
2547         gboolean do_delete = TRUE;
2548
2549         g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2550
2551         folder_view = modest_main_window_get_child_widget (main_window,
2552                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2553         if (!folder_view)
2554                 return;
2555
2556         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2557
2558         /* Show an error if it's an account */
2559         if (!TNY_IS_FOLDER (folder)) {
2560                 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2561                                                         _("mail_in_ui_folder_delete_error"));
2562                 g_object_unref (G_OBJECT (folder));
2563                 return ;
2564         }
2565
2566         /* Ask the user */      
2567         message =  g_strdup_printf (_("mcen_nc_delete_folder_text"), 
2568                                     tny_folder_get_name (TNY_FOLDER (folder)));
2569         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2570                                                             (const gchar *) message);
2571         g_free (message);
2572
2573         if (response != GTK_RESPONSE_OK) {
2574                 do_delete = FALSE;
2575         } else if (modest_platform_is_network_folderstore(folder) &&
2576                    !tny_device_is_online (modest_runtime_get_device())) {
2577                 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2578                 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2579                 g_object_unref(account);
2580         }
2581
2582         if (do_delete) {
2583                 ModestMailOperation *mail_op;
2584                 GtkTreeSelection *sel;
2585
2586                 /* Unselect the folder before deleting it to free the headers */
2587                 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2588                 gtk_tree_selection_unselect_all (sel);
2589
2590                 /* Create the mail operation */
2591                 mail_op =
2592                         modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE, 
2593                                                                        G_OBJECT(main_window),
2594                                                                        modest_ui_actions_delete_folder_error_handler,
2595                                                                        NULL);
2596
2597                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2598                                                  mail_op);
2599                 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2600                 g_object_unref (G_OBJECT (mail_op));
2601         }
2602
2603         g_object_unref (G_OBJECT (folder));
2604 }
2605
2606 void 
2607 modest_ui_actions_on_delete_folder (GtkAction *action,
2608                                      ModestMainWindow *main_window)
2609 {
2610         GtkWidget *folder_view;
2611         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2612
2613         delete_folder (main_window, FALSE);
2614         folder_view = modest_main_window_get_child_widget (main_window,
2615                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2616         if (!folder_view)
2617                 return;
2618         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2619 }
2620
2621 void 
2622 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2623 {
2624         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2625         
2626         delete_folder (main_window, TRUE);
2627 }
2628
2629
2630 static void
2631 show_error (GtkWidget *parent_widget, const gchar* text)
2632 {
2633         hildon_banner_show_information(parent_widget, NULL, text);
2634         
2635 #if 0
2636         GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2637         /*
2638           GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2639           (GtkDialogFlags)0,
2640           GTK_MESSAGE_ERROR,
2641           GTK_BUTTONS_OK,
2642           text ));
2643         */
2644                  
2645         gtk_dialog_run (dialog);
2646         gtk_widget_destroy (GTK_WIDGET (dialog));
2647 #endif
2648 }
2649
2650 void
2651 modest_ui_actions_on_password_requested (TnyAccountStore *account_store, 
2652                                          const gchar* server_account_name,
2653                                          gchar **username,
2654                                          gchar **password, 
2655                                          gboolean *cancel, 
2656                                          gboolean *remember,
2657                                          ModestMainWindow *main_window)
2658 {
2659         g_return_if_fail(server_account_name);
2660         /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2661         
2662         /* Initalize output parameters: */
2663         if (cancel)
2664                 *cancel = FALSE;
2665                 
2666         if (remember)
2667                 *remember = TRUE;
2668                 
2669 #ifdef MODEST_PLATFORM_MAEMO
2670         /* Maemo uses a different (awkward) button order,
2671          * It should probably just use gtk_alternative_dialog_button_order ().
2672          */
2673         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2674                                               NULL,
2675                                               GTK_DIALOG_MODAL,
2676                                               _("mcen_bd_dialog_ok"),
2677                                               GTK_RESPONSE_ACCEPT,
2678                                               _("mcen_bd_dialog_cancel"),
2679                                               GTK_RESPONSE_REJECT,
2680                                               NULL);
2681 #else
2682         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2683                                               NULL,
2684                                               GTK_DIALOG_MODAL,
2685                                               GTK_STOCK_CANCEL,
2686                                               GTK_RESPONSE_REJECT,
2687                                               GTK_STOCK_OK,
2688                                               GTK_RESPONSE_ACCEPT,
2689                                               NULL);
2690 #endif /* MODEST_PLATFORM_MAEMO */
2691
2692         gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2693         
2694         gchar *server_name = modest_server_account_get_hostname (
2695                 modest_runtime_get_account_mgr(), server_account_name);
2696         if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2697                 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2698                 *cancel = TRUE;
2699                 return;
2700         }
2701         
2702         /* This causes a warning because the logical ID has no %s in it, 
2703          * though the translation does, but there is not much we can do about that: */
2704         gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2705         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2706                             FALSE, FALSE, 0);
2707         g_free (txt);
2708         g_free (server_name);
2709         server_name = NULL;
2710
2711         /* username: */
2712         gchar *initial_username = modest_server_account_get_username (
2713                 modest_runtime_get_account_mgr(), server_account_name);
2714         
2715         GtkWidget *entry_username = gtk_entry_new ();
2716         if (initial_username)
2717                 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2718         /* Dim this if a connection has ever succeeded with this username,
2719          * as per the UI spec: */
2720         const gboolean username_known = 
2721                 modest_server_account_get_username_has_succeeded(
2722                         modest_runtime_get_account_mgr(), server_account_name);
2723         gtk_widget_set_sensitive (entry_username, !username_known);
2724         
2725 #ifdef MODEST_PLATFORM_MAEMO
2726         /* Auto-capitalization is the default, so let's turn it off: */
2727         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2728         
2729         /* Create a size group to be used by all captions.
2730          * Note that HildonCaption does not create a default size group if we do not specify one.
2731          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2732         GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2733         
2734         GtkWidget *caption = hildon_caption_new (sizegroup, 
2735                 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2736         gtk_widget_show (entry_username);
2737         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
2738                 FALSE, FALSE, MODEST_MARGIN_HALF);
2739         gtk_widget_show (caption);
2740 #else 
2741         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2742                             TRUE, FALSE, 0);
2743 #endif /* MODEST_PLATFORM_MAEMO */      
2744                             
2745         /* password: */
2746         GtkWidget *entry_password = gtk_entry_new ();
2747         gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2748         /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2749         
2750 #ifdef MODEST_PLATFORM_MAEMO
2751         /* Auto-capitalization is the default, so let's turn it off: */
2752         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password), 
2753                 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2754         
2755         caption = hildon_caption_new (sizegroup, 
2756                 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2757         gtk_widget_show (entry_password);
2758         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
2759                 FALSE, FALSE, MODEST_MARGIN_HALF);
2760         gtk_widget_show (caption);
2761         g_object_unref (sizegroup);
2762 #else 
2763         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2764                             TRUE, FALSE, 0);
2765 #endif /* MODEST_PLATFORM_MAEMO */      
2766                                 
2767 /* This is not in the Maemo UI spec:
2768         remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2769         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2770                             TRUE, FALSE, 0);
2771 */
2772
2773         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2774         
2775         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2776                 if (username) {
2777                         *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2778                         
2779                         modest_server_account_set_username (
2780                                  modest_runtime_get_account_mgr(), server_account_name, 
2781                                  *username);
2782                                  
2783                         const gboolean username_was_changed = 
2784                                 (strcmp (*username, initial_username) != 0);
2785                         if (username_was_changed) {
2786                                 g_warning ("%s: tinymail does not yet support changing the "
2787                                         "username in the get_password() callback.\n", __FUNCTION__);
2788                         }
2789                 }
2790                         
2791                 if (password) {
2792                         *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2793                         
2794                         /* We do not save the password in the configuration, 
2795                          * because this function is only called for passwords that should 
2796                          * not be remembered:
2797                         modest_server_account_set_password (
2798                                  modest_runtime_get_account_mgr(), server_account_name, 
2799                                  *password);
2800                         */
2801                 }
2802                 
2803                 if (cancel)
2804                         *cancel   = FALSE;
2805                         
2806         } else {
2807                 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2808                 
2809                 if (username)
2810                         *username = NULL;
2811                         
2812                 if (password)
2813                         *password = NULL;
2814                         
2815                 if (cancel)
2816                         *cancel   = TRUE;
2817         }
2818
2819 /* This is not in the Maemo UI spec:
2820         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2821                 *remember = TRUE;
2822         else
2823                 *remember = FALSE;
2824 */
2825
2826         gtk_widget_destroy (dialog);
2827         
2828         /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2829 }
2830
2831 void
2832 modest_ui_actions_on_cut (GtkAction *action,
2833                           ModestWindow *window)
2834 {
2835         GtkWidget *focused_widget;
2836         GtkClipboard *clipboard;
2837
2838         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2839         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2840         if (GTK_IS_EDITABLE (focused_widget)) {
2841                 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2842                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2843                 gtk_clipboard_store (clipboard);
2844         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2845                 GtkTextBuffer *buffer;
2846
2847                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2848                 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2849                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2850                 gtk_clipboard_store (clipboard);
2851         } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2852                 TnyList *header_list = modest_header_view_get_selected_headers (
2853                                 MODEST_HEADER_VIEW (focused_widget));
2854                 gboolean continue_download = FALSE;
2855                 gint num_of_unc_msgs;
2856
2857                 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2858
2859                 if (num_of_unc_msgs)
2860                         continue_download = connect_to_get_msg(
2861                                                                 GTK_WINDOW (window),
2862                                                                 num_of_unc_msgs);
2863
2864                 if (num_of_unc_msgs == 0 || continue_download) {
2865 /*                      modest_platform_information_banner (
2866                                         NULL, NULL, _CS("mcen_ib_getting_items"));*/
2867                         modest_header_view_cut_selection (
2868                                         MODEST_HEADER_VIEW (focused_widget));
2869                 }
2870
2871                 g_object_unref (header_list);
2872         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2873                 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2874         }
2875 }
2876
2877 void
2878 modest_ui_actions_on_copy (GtkAction *action,
2879                            ModestWindow *window)
2880 {
2881         GtkClipboard *clipboard;
2882         GtkWidget *focused_widget;
2883         gboolean copied = TRUE;
2884
2885         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2886         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2887
2888         if (GTK_IS_LABEL (focused_widget)) {
2889                 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2890                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2891                 gtk_clipboard_store (clipboard);
2892         } else if (GTK_IS_EDITABLE (focused_widget)) {
2893                 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2894                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2895                 gtk_clipboard_store (clipboard);
2896         } else if (GTK_IS_HTML (focused_widget)) {
2897                 gtk_html_copy (GTK_HTML (focused_widget));
2898                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2899                 gtk_clipboard_store (clipboard);
2900         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2901                 GtkTextBuffer *buffer;
2902                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2903                 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2904                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2905                 gtk_clipboard_store (clipboard);
2906         } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2907                 TnyList *header_list = modest_header_view_get_selected_headers (
2908                                 MODEST_HEADER_VIEW (focused_widget));
2909                 gboolean continue_download = FALSE;
2910                 gint num_of_unc_msgs;
2911
2912                 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2913
2914                 if (num_of_unc_msgs)
2915                         continue_download = connect_to_get_msg(
2916                                                                 GTK_WINDOW (window),
2917                                                                 num_of_unc_msgs);
2918
2919                 if (num_of_unc_msgs == 0 || continue_download) {
2920                         modest_platform_information_banner (
2921                                         NULL, NULL, _CS("mcen_ib_getting_items"));
2922                         modest_header_view_copy_selection (
2923                                         MODEST_HEADER_VIEW (focused_widget));
2924                 } else
2925                         copied = FALSE;
2926
2927                 g_object_unref (header_list);
2928
2929         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2930                 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2931         }
2932
2933         /* Show information banner if there was a copy to clipboard */
2934         if(copied)
2935                 modest_platform_information_banner (
2936                                 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2937 }
2938
2939 void
2940 modest_ui_actions_on_undo (GtkAction *action,
2941                            ModestWindow *window)
2942 {
2943         ModestEmailClipboard *clipboard = NULL;
2944
2945         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2946                 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2947         } else if (MODEST_IS_MAIN_WINDOW (window)) {
2948                 /* Clear clipboard source */
2949                 clipboard = modest_runtime_get_email_clipboard ();
2950                 modest_email_clipboard_clear (clipboard);               
2951         }
2952         else {
2953                 g_return_if_reached ();
2954         }
2955 }
2956
2957 void
2958 modest_ui_actions_on_redo (GtkAction *action,
2959                            ModestWindow *window)
2960 {
2961         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2962                 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2963         }
2964         else {
2965                 g_return_if_reached ();
2966         }
2967 }
2968
2969
2970 static void
2971 paste_msgs_cb (const GObject *object, gpointer user_data)
2972 {
2973         g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2974         g_return_if_fail (GTK_IS_WIDGET (user_data));
2975         
2976         /* destroy information note */
2977         gtk_widget_destroy (GTK_WIDGET(user_data));
2978 }
2979
2980
2981 static void
2982 paste_as_attachment_free (gpointer data)
2983 {
2984         PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2985
2986         gtk_widget_destroy (helper->banner);
2987         g_object_unref (helper->banner);
2988         g_free (helper);
2989 }
2990
2991 static void
2992 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2993                             TnyHeader *header,
2994                             TnyMsg *msg,
2995                             gpointer userdata)
2996 {
2997         PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2998         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2999
3000         if (msg == NULL)
3001                 return;
3002
3003         modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3004         
3005 }
3006
3007 void
3008 modest_ui_actions_on_paste (GtkAction *action,
3009                             ModestWindow *window)
3010 {
3011         GtkWidget *focused_widget = NULL;
3012         GtkWidget *inf_note = NULL;
3013         ModestMailOperation *mail_op = NULL;
3014
3015         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3016         if (GTK_IS_EDITABLE (focused_widget)) {
3017                 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3018         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3019                 ModestEmailClipboard *e_clipboard = NULL;
3020                 e_clipboard = modest_runtime_get_email_clipboard ();
3021                 if (modest_email_clipboard_cleared (e_clipboard)) {
3022                         GtkTextBuffer *buffer;
3023                         GtkClipboard *clipboard;
3024
3025                         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3026                         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3027                         gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3028                 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3029                         ModestMailOperation *mail_op;
3030                         TnyFolder *src_folder;
3031                         TnyList *data;
3032                         gboolean delete;
3033                         PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3034                         helper->window = MODEST_MSG_EDIT_WINDOW (window);
3035                         helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3036                                                                            _CS("ckct_nw_pasting"));
3037                         modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3038                         mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
3039                                                              G_OBJECT (window));
3040                         if (helper->banner != NULL) {
3041                                 g_object_ref (G_OBJECT (helper->banner));
3042                                 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3043                                 gtk_widget_show (GTK_WIDGET (helper->banner));
3044                         }
3045
3046                         if (data != NULL) {
3047                                 modest_mail_operation_get_msgs_full (mail_op, 
3048                                                                      data,
3049                                                                      (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3050                                                                      helper,
3051                                                                      paste_as_attachment_free);
3052                         }
3053                 }
3054         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3055                 ModestEmailClipboard *clipboard = NULL;
3056                 TnyFolder *src_folder = NULL;
3057                 TnyFolderStore *folder_store = NULL;
3058                 TnyList *data = NULL;           
3059                 gboolean delete = FALSE;
3060                 
3061                 /* Check clipboard source */
3062                 clipboard = modest_runtime_get_email_clipboard ();
3063                 if (modest_email_clipboard_cleared (clipboard)) 
3064                         return;
3065                 
3066                 /* Get elements to paste */
3067                 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3068
3069                 /* Create a new mail operation */
3070                 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
3071                 
3072                 /* Get destination folder */
3073                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3074
3075                 /* transfer messages  */
3076                 if (data != NULL) {
3077                         gint response = 0;
3078
3079                         /* Ask for user confirmation */
3080                         response = msgs_move_to_confirmation (GTK_WINDOW (window), 
3081                                                               TNY_FOLDER (folder_store), 
3082                                                               delete,
3083                                                               data);
3084                         
3085                         if (response == GTK_RESPONSE_OK) {
3086                                 /* Launch notification */
3087                                 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL, 
3088                                                                              _CS("ckct_nw_pasting"));
3089                                 if (inf_note != NULL)  {
3090                                         gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3091                                         gtk_widget_show (GTK_WIDGET(inf_note));
3092                                 }
3093
3094                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3095                                 modest_mail_operation_xfer_msgs (mail_op, 
3096                                                                  data,
3097                                                                  TNY_FOLDER (folder_store),
3098                                                                  delete,
3099                                                                  paste_msgs_cb,
3100                                                                  inf_note);                             
3101                         } else {
3102                                 g_object_unref (mail_op);
3103                         }
3104                         
3105                 } else if (src_folder != NULL) {                        
3106                         /* Launch notification */
3107                         inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL, 
3108                                                                      _CS("ckct_nw_pasting"));
3109                         if (inf_note != NULL)  {
3110                                 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3111                                 gtk_widget_show (GTK_WIDGET(inf_note));
3112                         }
3113                         
3114                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3115                         modest_mail_operation_xfer_folder (mail_op, 
3116                                                            src_folder,
3117                                                            folder_store,
3118                                                            delete,
3119                                                            paste_msgs_cb,
3120                                                            inf_note);
3121                 }
3122
3123                 /* Free */
3124                 if (data != NULL) 
3125                         g_object_unref (data);
3126                 if (src_folder != NULL) 
3127                         g_object_unref (src_folder);
3128                 if (folder_store != NULL) 
3129                         g_object_unref (folder_store);
3130         }
3131 }
3132
3133
3134 void
3135 modest_ui_actions_on_select_all (GtkAction *action,
3136                                  ModestWindow *window)
3137 {
3138         GtkWidget *focused_widget;
3139
3140         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3141         if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3142                 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3143         } else if (GTK_IS_LABEL (focused_widget)) {
3144                 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3145         } else if (GTK_IS_EDITABLE (focused_widget)) {
3146                 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3147         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3148                 GtkTextBuffer *buffer;
3149                 GtkTextIter start, end;
3150
3151                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3152                 gtk_text_buffer_get_start_iter (buffer, &start);
3153                 gtk_text_buffer_get_end_iter (buffer, &end);
3154                 gtk_text_buffer_select_range (buffer, &start, &end);
3155         } else if (GTK_IS_HTML (focused_widget)) {
3156                 gtk_html_select_all (GTK_HTML (focused_widget));
3157         } else if (MODEST_IS_MAIN_WINDOW (window)) {
3158                 GtkWidget *header_view = focused_widget;
3159                 GtkTreeSelection *selection = NULL;
3160                 
3161                 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3162                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3163                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
3164                 }
3165                                 
3166                 /* Disable window dimming management */
3167                 modest_window_disable_dimming (MODEST_WINDOW(window));
3168                 
3169                 /* Select all messages */
3170                 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3171                 gtk_tree_selection_select_all (selection);
3172
3173                 /* Set focuse on header view */
3174                 gtk_widget_grab_focus (header_view);
3175
3176
3177                 /* Enable window dimming management */
3178                 modest_window_enable_dimming (MODEST_WINDOW(window));
3179                 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3180         }
3181
3182 }
3183
3184 void
3185 modest_ui_actions_on_mark_as_read (GtkAction *action,
3186                                    ModestWindow *window)
3187 {       
3188         g_return_if_fail (MODEST_IS_WINDOW(window));
3189                 
3190         /* Mark each header as read */
3191         do_headers_action (window, headers_action_mark_as_read, NULL);
3192 }
3193
3194 void
3195 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3196                                      ModestWindow *window)
3197 {       
3198         g_return_if_fail (MODEST_IS_WINDOW(window));
3199                 
3200         /* Mark each header as read */
3201         do_headers_action (window, headers_action_mark_as_unread, NULL);
3202 }
3203