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