* Added a callback for the save_to_drafts operation
[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         /* Offer the connection dialog, if necessary: */        
2207         if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2208                 return;
2209         
2210         /* FIXME: Code added just for testing. The final version will
2211            use the send queue provided by tinymail and some
2212            classifier */
2213         ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2214         gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2215         if (!account_name) 
2216                 account_name = modest_account_mgr_get_default_account (account_mgr);
2217                 
2218         if (!account_name) {
2219                 /* Run account setup wizard */
2220                 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window)))
2221                         return;
2222         }
2223         
2224         MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2225
2226         if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2227                 account_name = g_strdup (data->account_name);
2228         }
2229         
2230         /* Get the currently-active transport account for this modest account: */
2231         TnyTransportAccount *transport_account =
2232                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2233                                       (modest_runtime_get_account_store(),
2234                                        account_name));
2235         if (!transport_account) {
2236                 /* Run account setup wizard */
2237                 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2238                         return;
2239         }
2240         
2241         gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2242
2243         /* Create the mail operation */
2244         ModestMailOperation *mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2245         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2246
2247         modest_mail_operation_send_new_mail (mail_operation,
2248                                              transport_account,
2249                                              data->draft_msg,
2250                                              from,
2251                                              data->to, 
2252                                              data->cc, 
2253                                              data->bcc,
2254                                              data->subject, 
2255                                              data->plain_body, 
2256                                              data->html_body,
2257                                              data->attachments,
2258                                              data->images,
2259                                              data->priority_flags);
2260                                              
2261         /* Free data: */
2262         g_free (from);
2263         g_free (account_name);
2264         g_object_unref (G_OBJECT (transport_account));
2265         g_object_unref (G_OBJECT (mail_operation));
2266
2267         modest_msg_edit_window_free_msg_data (edit_window, data);
2268         modest_msg_edit_window_set_sent (edit_window, TRUE);
2269
2270         /* Save settings and close the window: */
2271         modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2272 }
2273
2274 void 
2275 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2276                                   ModestMsgEditWindow *window)
2277 {
2278         ModestMsgEditFormatState *format_state = NULL;
2279
2280         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2281         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2282
2283         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2284                 return;
2285
2286         format_state = modest_msg_edit_window_get_format_state (window);
2287         g_return_if_fail (format_state != NULL);
2288
2289         format_state->bold = gtk_toggle_action_get_active (action);
2290         modest_msg_edit_window_set_format_state (window, format_state);
2291         g_free (format_state);
2292         
2293 }
2294
2295 void 
2296 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2297                                      ModestMsgEditWindow *window)
2298 {
2299         ModestMsgEditFormatState *format_state = NULL;
2300
2301         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2302         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2303
2304         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2305                 return;
2306
2307         format_state = modest_msg_edit_window_get_format_state (window);
2308         g_return_if_fail (format_state != NULL);
2309
2310         format_state->italics = gtk_toggle_action_get_active (action);
2311         modest_msg_edit_window_set_format_state (window, format_state);
2312         g_free (format_state);
2313         
2314 }
2315
2316 void 
2317 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2318                                      ModestMsgEditWindow *window)
2319 {
2320         ModestMsgEditFormatState *format_state = NULL;
2321
2322         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2323         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2324
2325         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2326                 return;
2327
2328         format_state = modest_msg_edit_window_get_format_state (window);
2329         g_return_if_fail (format_state != NULL);
2330
2331         format_state->bullet = gtk_toggle_action_get_active (action);
2332         modest_msg_edit_window_set_format_state (window, format_state);
2333         g_free (format_state);
2334         
2335 }
2336
2337 void 
2338 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2339                                      GtkRadioAction *selected,
2340                                      ModestMsgEditWindow *window)
2341 {
2342         ModestMsgEditFormatState *format_state = NULL;
2343         GtkJustification value;
2344
2345         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2346
2347         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2348                 return;
2349
2350         value = gtk_radio_action_get_current_value (selected);
2351
2352         format_state = modest_msg_edit_window_get_format_state (window);
2353         g_return_if_fail (format_state != NULL);
2354
2355         format_state->justification = value;
2356         modest_msg_edit_window_set_format_state (window, format_state);
2357         g_free (format_state);
2358 }
2359
2360 void 
2361 modest_ui_actions_on_select_editor_color (GtkAction *action,
2362                                           ModestMsgEditWindow *window)
2363 {
2364         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2365         g_return_if_fail (GTK_IS_ACTION (action));
2366
2367         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2368                 return;
2369
2370         modest_msg_edit_window_select_color (window);
2371 }
2372
2373 void 
2374 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2375                                                      ModestMsgEditWindow *window)
2376 {
2377         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2378         g_return_if_fail (GTK_IS_ACTION (action));
2379
2380         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2381                 return;
2382
2383         modest_msg_edit_window_select_background_color (window);
2384 }
2385
2386 void 
2387 modest_ui_actions_on_insert_image (GtkAction *action,
2388                                    ModestMsgEditWindow *window)
2389 {
2390         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2391         g_return_if_fail (GTK_IS_ACTION (action));
2392
2393         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2394                 return;
2395
2396         modest_msg_edit_window_insert_image (window);
2397 }
2398
2399 void 
2400 modest_ui_actions_on_attach_file (GtkAction *action,
2401                                   ModestMsgEditWindow *window)
2402 {
2403         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2404         g_return_if_fail (GTK_IS_ACTION (action));
2405
2406         modest_msg_edit_window_offer_attach_file (window);
2407 }
2408
2409 void 
2410 modest_ui_actions_on_remove_attachments (GtkAction *action,
2411                                          ModestMsgEditWindow *window)
2412 {
2413         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2414         g_return_if_fail (GTK_IS_ACTION (action));
2415
2416         modest_msg_edit_window_remove_attachments (window, NULL);
2417 }
2418
2419 static void
2420 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2421                                             gpointer user_data)
2422 {
2423         ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2424         const GError *error = modest_mail_operation_get_error (mail_op);
2425
2426         if(error) {
2427                 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2428                                                     _("mail_in_ui_folder_create_error"));
2429         }
2430 }
2431
2432 static void
2433 modest_ui_actions_create_folder(GtkWidget *parent_window,
2434                                 GtkWidget *folder_view)
2435 {
2436         TnyFolderStore *parent_folder;
2437
2438         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2439         
2440         if (parent_folder) {
2441                 gboolean finished = FALSE;
2442                 gint result;
2443                 gchar *folder_name = NULL, *suggested_name = NULL;
2444                 const gchar *proto_str = NULL;
2445                 TnyAccount *account;
2446
2447                 if (TNY_IS_ACCOUNT (parent_folder))
2448                         account = g_object_ref (parent_folder);
2449                 else
2450                         account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2451                 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2452
2453                 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2454                     MODEST_PROTOCOL_STORE_POP) {
2455                         finished = TRUE;
2456                         hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2457                 }
2458                 g_object_unref (account);
2459
2460                 /* Run the new folder dialog */
2461                 while (!finished) {
2462                         result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2463                                                                         parent_folder,
2464                                                                         suggested_name,
2465                                                                         &folder_name);
2466
2467                         g_free (suggested_name);
2468                         suggested_name = NULL;
2469
2470                         if (result == GTK_RESPONSE_REJECT) {
2471                                 finished = TRUE;
2472                         } else {
2473                                 ModestMailOperation *mail_op;
2474                                 TnyFolder *new_folder = NULL;
2475
2476                                 mail_op  = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2477                                                                                           modest_ui_actions_new_folder_error_handler,
2478                                                                                           parent_window);
2479
2480                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
2481                                                                  mail_op);
2482                                 new_folder = modest_mail_operation_create_folder (mail_op,
2483                                                                                   parent_folder,
2484                                                                                   (const gchar *) folder_name);
2485                                 if (new_folder) {
2486                                         modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), 
2487                                                                           new_folder, TRUE);
2488
2489                                         g_object_unref (new_folder);
2490                                         finished = TRUE;
2491                                 }
2492                                 g_object_unref (mail_op);
2493                         }
2494
2495                         suggested_name = folder_name;
2496                         folder_name = NULL;
2497                 }
2498
2499                 g_object_unref (parent_folder);
2500         }
2501 }
2502
2503 void 
2504 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2505 {
2506         GtkWidget *folder_view;
2507         
2508         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2509
2510         folder_view = modest_main_window_get_child_widget (main_window,
2511                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2512         if (!folder_view)
2513                 return;
2514
2515         modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2516 }
2517
2518 static void
2519 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2520                                                gpointer user_data)
2521 {
2522         ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2523         const GError *error = NULL;
2524         const gchar *message = NULL;
2525         
2526         /* Get error message */
2527         error = modest_mail_operation_get_error (mail_op);
2528         if (!error)
2529                 g_return_if_reached ();
2530
2531         switch (error->code) {
2532         case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2533                 message = _CS("ckdg_ib_folder_already_exists");
2534                 break;
2535         default:
2536                 g_return_if_reached ();
2537         }
2538
2539         modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2540 }
2541
2542 void 
2543 modest_ui_actions_on_rename_folder (GtkAction *action,
2544                                      ModestMainWindow *main_window)
2545 {
2546         TnyFolderStore *folder;
2547         GtkWidget *folder_view;
2548         GtkWidget *header_view; 
2549
2550         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2551
2552         folder_view = modest_main_window_get_child_widget (main_window,
2553                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2554         if (!folder_view)
2555                 return;
2556
2557         header_view = modest_main_window_get_child_widget (main_window,
2558                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2559         
2560         if (!header_view)
2561                 return;
2562
2563         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2564
2565         if (!folder)
2566                 return;
2567
2568         if (TNY_IS_FOLDER (folder)) {
2569                 gchar *folder_name;
2570                 gint response;
2571                 const gchar *current_name;
2572                 TnyFolderStore *parent;
2573                 gboolean do_rename = TRUE;
2574
2575                 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2576                 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2577                 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), 
2578                                                                      parent, current_name, 
2579                                                                      &folder_name);
2580                 g_object_unref (parent);
2581
2582                 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2583                         do_rename = FALSE;
2584                 } else if (modest_platform_is_network_folderstore(folder) &&
2585                            !tny_device_is_online (modest_runtime_get_device())) {
2586                         TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2587                         do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2588                         g_object_unref(account);
2589                 }
2590
2591                 if (do_rename) {
2592                         ModestMailOperation *mail_op;
2593                         GtkTreeSelection *sel = NULL;
2594
2595                         mail_op = 
2596                                 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2597                                                                                modest_ui_actions_rename_folder_error_handler,
2598                                                                                main_window);
2599
2600                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2601                                                          mail_op);
2602
2603                         /* Clear the headers view */
2604                         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2605                         gtk_tree_selection_unselect_all (sel);
2606
2607                         /* Select *after* the changes */
2608                         modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2609                                                           TNY_FOLDER(folder), TRUE);
2610
2611                         /* Actually rename the folder */
2612                         modest_mail_operation_rename_folder (mail_op,
2613                                                              TNY_FOLDER (folder),
2614                                                              (const gchar *) folder_name);
2615
2616                         g_object_unref (mail_op);
2617                         g_free (folder_name);
2618                 }
2619         }
2620         g_object_unref (folder);
2621 }
2622
2623 static void
2624 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2625                                                gpointer user_data)
2626 {
2627         GObject *win = modest_mail_operation_get_source (mail_op);
2628
2629         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2630                                                 _("mail_in_ui_folder_delete_error"));
2631         g_object_unref (win);
2632 }
2633
2634 static gboolean
2635 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash) 
2636 {
2637         TnyFolderStore *folder;
2638         GtkWidget *folder_view;
2639         gint response;
2640         gchar *message;
2641         gboolean do_delete = TRUE;
2642
2643         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2644
2645         folder_view = modest_main_window_get_child_widget (main_window,
2646                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2647         if (!folder_view)
2648                 return FALSE;
2649
2650         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2651
2652         /* Show an error if it's an account */
2653         if (!TNY_IS_FOLDER (folder)) {
2654                 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2655                                                         _("mail_in_ui_folder_delete_error"));
2656                 g_object_unref (G_OBJECT (folder));
2657                 return FALSE;
2658         }
2659
2660         /* Ask the user */      
2661         message =  g_strdup_printf (_("mcen_nc_delete_folder_text"), 
2662                                     tny_folder_get_name (TNY_FOLDER (folder)));
2663         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2664                                                             (const gchar *) message);
2665         g_free (message);
2666
2667         if (response != GTK_RESPONSE_OK) {
2668                 do_delete = FALSE;
2669         } else if (modest_platform_is_network_folderstore(folder) &&
2670                    !tny_device_is_online (modest_runtime_get_device())) {
2671                 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2672                 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2673                 g_object_unref(account);
2674         }
2675
2676         if (do_delete) {
2677                 ModestMailOperation *mail_op;
2678                 GtkTreeSelection *sel;
2679
2680                 /* Unselect the folder before deleting it to free the headers */
2681                 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2682                 gtk_tree_selection_unselect_all (sel);
2683
2684                 /* Create the mail operation */
2685                 mail_op =
2686                         modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2687                                                                        modest_ui_actions_delete_folder_error_handler,
2688                                                                        NULL);
2689
2690                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2691                                                  mail_op);
2692                 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2693                 g_object_unref (G_OBJECT (mail_op));
2694         }
2695
2696         g_object_unref (G_OBJECT (folder));
2697
2698         return do_delete;
2699 }
2700
2701 void 
2702 modest_ui_actions_on_delete_folder (GtkAction *action,
2703                                      ModestMainWindow *main_window)
2704 {
2705         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2706
2707         if (delete_folder (main_window, FALSE)) {
2708                 GtkWidget *folder_view;
2709
2710                 folder_view = modest_main_window_get_child_widget (main_window,
2711                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2712                 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2713         }
2714 }
2715
2716 void 
2717 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2718 {
2719         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2720         
2721         delete_folder (main_window, TRUE);
2722 }
2723
2724
2725 static void
2726 show_error (GtkWidget *parent_widget, const gchar* text)
2727 {
2728         hildon_banner_show_information(parent_widget, NULL, text);
2729         
2730 #if 0
2731         GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2732         /*
2733           GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2734           (GtkDialogFlags)0,
2735           GTK_MESSAGE_ERROR,
2736           GTK_BUTTONS_OK,
2737           text ));
2738         */
2739                  
2740         gtk_dialog_run (dialog);
2741         gtk_widget_destroy (GTK_WIDGET (dialog));
2742 #endif
2743 }
2744
2745 void
2746 modest_ui_actions_on_password_requested (TnyAccountStore *account_store, 
2747                                          const gchar* server_account_name,
2748                                          gchar **username,
2749                                          gchar **password, 
2750                                          gboolean *cancel, 
2751                                          gboolean *remember,
2752                                          ModestMainWindow *main_window)
2753 {
2754         g_return_if_fail(server_account_name);
2755         /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2756         
2757         /* Initalize output parameters: */
2758         if (cancel)
2759                 *cancel = FALSE;
2760                 
2761         if (remember)
2762                 *remember = TRUE;
2763                 
2764 #ifdef MODEST_PLATFORM_MAEMO
2765         /* Maemo uses a different (awkward) button order,
2766          * It should probably just use gtk_alternative_dialog_button_order ().
2767          */
2768         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2769                                               NULL,
2770                                               GTK_DIALOG_MODAL,
2771                                               _("mcen_bd_dialog_ok"),
2772                                               GTK_RESPONSE_ACCEPT,
2773                                               _("mcen_bd_dialog_cancel"),
2774                                               GTK_RESPONSE_REJECT,
2775                                               NULL);
2776 #else
2777         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2778                                               NULL,
2779                                               GTK_DIALOG_MODAL,
2780                                               GTK_STOCK_CANCEL,
2781                                               GTK_RESPONSE_REJECT,
2782                                               GTK_STOCK_OK,
2783                                               GTK_RESPONSE_ACCEPT,
2784                                               NULL);
2785 #endif /* MODEST_PLATFORM_MAEMO */
2786
2787         gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2788         
2789         gchar *server_name = modest_account_mgr_get_server_account_hostname (
2790                 modest_runtime_get_account_mgr(), server_account_name);
2791         if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2792                 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2793                 *cancel = TRUE;
2794                 return;
2795         }
2796         
2797         /* This causes a warning because the logical ID has no %s in it, 
2798          * though the translation does, but there is not much we can do about that: */
2799         gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2800         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2801                             FALSE, FALSE, 0);
2802         g_free (txt);
2803         g_free (server_name);
2804         server_name = NULL;
2805
2806         /* username: */
2807         gchar *initial_username = modest_account_mgr_get_server_account_username (
2808                 modest_runtime_get_account_mgr(), server_account_name);
2809         
2810         GtkWidget *entry_username = gtk_entry_new ();
2811         if (initial_username)
2812                 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2813         /* Dim this if a connection has ever succeeded with this username,
2814          * as per the UI spec: */
2815         const gboolean username_known = 
2816                 modest_account_mgr_get_server_account_username_has_succeeded(
2817                         modest_runtime_get_account_mgr(), server_account_name);
2818         gtk_widget_set_sensitive (entry_username, !username_known);
2819         
2820 #ifdef MODEST_PLATFORM_MAEMO
2821         /* Auto-capitalization is the default, so let's turn it off: */
2822         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2823         
2824         /* Create a size group to be used by all captions.
2825          * Note that HildonCaption does not create a default size group if we do not specify one.
2826          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2827         GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2828         
2829         GtkWidget *caption = hildon_caption_new (sizegroup, 
2830                 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2831         gtk_widget_show (entry_username);
2832         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
2833                 FALSE, FALSE, MODEST_MARGIN_HALF);
2834         gtk_widget_show (caption);
2835 #else 
2836         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2837                             TRUE, FALSE, 0);
2838 #endif /* MODEST_PLATFORM_MAEMO */      
2839                             
2840         /* password: */
2841         GtkWidget *entry_password = gtk_entry_new ();
2842         gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2843         /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2844         
2845 #ifdef MODEST_PLATFORM_MAEMO
2846         /* Auto-capitalization is the default, so let's turn it off: */
2847         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password), 
2848                 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2849         
2850         caption = hildon_caption_new (sizegroup, 
2851                 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2852         gtk_widget_show (entry_password);
2853         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
2854                 FALSE, FALSE, MODEST_MARGIN_HALF);
2855         gtk_widget_show (caption);
2856         g_object_unref (sizegroup);
2857 #else 
2858         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2859                             TRUE, FALSE, 0);
2860 #endif /* MODEST_PLATFORM_MAEMO */      
2861
2862         if (initial_username != NULL)
2863                 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
2864                                 
2865 /* This is not in the Maemo UI spec:
2866         remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2867         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2868                             TRUE, FALSE, 0);
2869 */
2870
2871         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2872         
2873         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2874                 if (username) {
2875                         *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2876                         
2877                         modest_account_mgr_set_server_account_username (
2878                                  modest_runtime_get_account_mgr(), server_account_name, 
2879                                  *username);
2880                                  
2881                         const gboolean username_was_changed = 
2882                                 (strcmp (*username, initial_username) != 0);
2883                         if (username_was_changed) {
2884                                 g_warning ("%s: tinymail does not yet support changing the "
2885                                         "username in the get_password() callback.\n", __FUNCTION__);
2886                         }
2887                 }
2888                         
2889                 if (password) {
2890                         *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2891                         
2892                         /* We do not save the password in the configuration, 
2893                          * because this function is only called for passwords that should 
2894                          * not be remembered:
2895                         modest_server_account_set_password (
2896                                  modest_runtime_get_account_mgr(), server_account_name, 
2897                                  *password);
2898                         */
2899                 }
2900                 
2901                 if (cancel)
2902                         *cancel   = FALSE;
2903                         
2904         } else {
2905                 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2906                 
2907                 if (username)
2908                         *username = NULL;
2909                         
2910                 if (password)
2911                         *password = NULL;
2912                         
2913                 if (cancel)
2914                         *cancel   = TRUE;
2915         }
2916
2917 /* This is not in the Maemo UI spec:
2918         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2919                 *remember = TRUE;
2920         else
2921                 *remember = FALSE;
2922 */
2923
2924         gtk_widget_destroy (dialog);
2925         
2926         /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2927 }
2928
2929 void
2930 modest_ui_actions_on_cut (GtkAction *action,
2931                           ModestWindow *window)
2932 {
2933         GtkWidget *focused_widget;
2934         GtkClipboard *clipboard;
2935
2936         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2937         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2938         if (GTK_IS_EDITABLE (focused_widget)) {
2939                 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2940                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2941                 gtk_clipboard_store (clipboard);
2942         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2943                 GtkTextBuffer *buffer;
2944
2945                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2946                 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2947                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2948                 gtk_clipboard_store (clipboard);
2949         } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2950                 TnyList *header_list = modest_header_view_get_selected_headers (
2951                                 MODEST_HEADER_VIEW (focused_widget));
2952                 gboolean continue_download = FALSE;
2953                 gint num_of_unc_msgs;
2954
2955                 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2956
2957                 if (num_of_unc_msgs)
2958                         continue_download = connect_to_get_msg(
2959                                                                 GTK_WINDOW (window),
2960                                                                 num_of_unc_msgs);
2961
2962                 if (num_of_unc_msgs == 0 || continue_download) {
2963 /*                      modest_platform_information_banner (
2964                                         NULL, NULL, _CS("mcen_ib_getting_items"));*/
2965                         modest_header_view_cut_selection (
2966                                         MODEST_HEADER_VIEW (focused_widget));
2967                 }
2968
2969                 g_object_unref (header_list);
2970         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2971                 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2972         }
2973 }
2974
2975 void
2976 modest_ui_actions_on_copy (GtkAction *action,
2977                            ModestWindow *window)
2978 {
2979         GtkClipboard *clipboard;
2980         GtkWidget *focused_widget;
2981         gboolean copied = TRUE;
2982
2983         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2984         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2985
2986         if (GTK_IS_LABEL (focused_widget)) {
2987                 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2988                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2989                 gtk_clipboard_store (clipboard);
2990         } else if (GTK_IS_EDITABLE (focused_widget)) {
2991                 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2992                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2993                 gtk_clipboard_store (clipboard);
2994         } else if (GTK_IS_HTML (focused_widget)) {
2995                 gtk_html_copy (GTK_HTML (focused_widget));
2996                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2997                 gtk_clipboard_store (clipboard);
2998         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2999                 GtkTextBuffer *buffer;
3000                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3001                 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3002                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3003                 gtk_clipboard_store (clipboard);
3004         } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3005                 TnyList *header_list = modest_header_view_get_selected_headers (
3006                                 MODEST_HEADER_VIEW (focused_widget));
3007                 gboolean continue_download = FALSE;
3008                 gint num_of_unc_msgs;
3009
3010                 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3011
3012                 if (num_of_unc_msgs)
3013                         continue_download = connect_to_get_msg(
3014                                                                 GTK_WINDOW (window),
3015                                                                 num_of_unc_msgs);
3016
3017                 if (num_of_unc_msgs == 0 || continue_download) {
3018                         modest_platform_information_banner (
3019                                         NULL, NULL, _CS("mcen_ib_getting_items"));
3020                         modest_header_view_copy_selection (
3021                                         MODEST_HEADER_VIEW (focused_widget));
3022                 } else
3023                         copied = FALSE;
3024
3025                 g_object_unref (header_list);
3026
3027         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3028                 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3029         }
3030
3031         /* Show information banner if there was a copy to clipboard */
3032         if(copied)
3033                 modest_platform_information_banner (
3034                                 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3035 }
3036
3037 void
3038 modest_ui_actions_on_undo (GtkAction *action,
3039                            ModestWindow *window)
3040 {
3041         ModestEmailClipboard *clipboard = NULL;
3042
3043         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3044                 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3045         } else if (MODEST_IS_MAIN_WINDOW (window)) {
3046                 /* Clear clipboard source */
3047                 clipboard = modest_runtime_get_email_clipboard ();
3048                 modest_email_clipboard_clear (clipboard);               
3049         }
3050         else {
3051                 g_return_if_reached ();
3052         }
3053 }
3054
3055 void
3056 modest_ui_actions_on_redo (GtkAction *action,
3057                            ModestWindow *window)
3058 {
3059         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3060                 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3061         }
3062         else {
3063                 g_return_if_reached ();
3064         }
3065 }
3066
3067
3068 static void
3069 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3070 {
3071         /* destroy information note */
3072         gtk_widget_destroy (GTK_WIDGET(user_data));
3073 }
3074
3075
3076 static void
3077 paste_as_attachment_free (gpointer data)
3078 {
3079         PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3080
3081         gtk_widget_destroy (helper->banner);
3082         g_object_unref (helper->banner);
3083         g_free (helper);
3084 }
3085
3086 static void
3087 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3088                             TnyHeader *header,
3089                             TnyMsg *msg,
3090                             gpointer userdata)
3091 {
3092         PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3093         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3094
3095         if (msg == NULL)
3096                 return;
3097
3098         modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3099         
3100 }
3101
3102 void
3103 modest_ui_actions_on_paste (GtkAction *action,
3104                             ModestWindow *window)
3105 {
3106         GtkWidget *focused_widget = NULL;
3107         GtkWidget *inf_note = NULL;
3108         ModestMailOperation *mail_op = NULL;
3109
3110         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3111         if (GTK_IS_EDITABLE (focused_widget)) {
3112                 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3113         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3114                 ModestEmailClipboard *e_clipboard = NULL;
3115                 e_clipboard = modest_runtime_get_email_clipboard ();
3116                 if (modest_email_clipboard_cleared (e_clipboard)) {
3117                         GtkTextBuffer *buffer;
3118                         GtkClipboard *clipboard;
3119
3120                         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3121                         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3122                         gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3123                 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3124                         ModestMailOperation *mail_op;
3125                         TnyFolder *src_folder;
3126                         TnyList *data;
3127                         gboolean delete;
3128                         PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3129                         helper->window = MODEST_MSG_EDIT_WINDOW (window);
3130                         helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3131                                                                            _CS("ckct_nw_pasting"));
3132                         modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3133                         mail_op = modest_mail_operation_new (G_OBJECT (window));
3134                         if (helper->banner != NULL) {
3135                                 g_object_ref (G_OBJECT (helper->banner));
3136                                 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3137                                 gtk_widget_show (GTK_WIDGET (helper->banner));
3138                         }
3139
3140                         if (data != NULL) {
3141                                 modest_mail_operation_get_msgs_full (mail_op, 
3142                                                                      data,
3143                                                                      (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3144                                                                      helper,
3145                                                                      paste_as_attachment_free);
3146                         }
3147                 }
3148         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3149                 ModestEmailClipboard *clipboard = NULL;
3150                 TnyFolder *src_folder = NULL;
3151                 TnyFolderStore *folder_store = NULL;
3152                 TnyList *data = NULL;           
3153                 gboolean delete = FALSE;
3154                 
3155                 /* Check clipboard source */
3156                 clipboard = modest_runtime_get_email_clipboard ();
3157                 if (modest_email_clipboard_cleared (clipboard)) 
3158                         return;
3159                 
3160                 /* Get elements to paste */
3161                 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3162
3163                 /* Create a new mail operation */
3164                 mail_op = modest_mail_operation_new (G_OBJECT(window));
3165                 
3166                 /* Get destination folder */
3167                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3168
3169                 /* transfer messages  */
3170                 if (data != NULL) {
3171                         gint response = 0;
3172
3173                         /* Ask for user confirmation */
3174                         response = 
3175                                 modest_ui_actions_msgs_move_to_confirmation (GTK_WINDOW (window), 
3176                                                                              TNY_FOLDER (folder_store), 
3177                                                                              delete,
3178                                                                              data);
3179                         
3180                         if (response == GTK_RESPONSE_OK) {
3181                                 /* Launch notification */
3182                                 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL, 
3183                                                                              _CS("ckct_nw_pasting"));
3184                                 if (inf_note != NULL)  {
3185                                         gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3186                                         gtk_widget_show (GTK_WIDGET(inf_note));
3187                                 }
3188
3189                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3190                                 modest_mail_operation_xfer_msgs (mail_op, 
3191                                                                  data,
3192                                                                  TNY_FOLDER (folder_store),
3193                                                                  delete,
3194                                                                  destroy_information_note,
3195                                                                  inf_note);                             
3196                         } else {
3197                                 g_object_unref (mail_op);
3198                         }
3199                         
3200                 } else if (src_folder != NULL) {                        
3201                         /* Launch notification */
3202                         inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL, 
3203                                                                      _CS("ckct_nw_pasting"));
3204                         if (inf_note != NULL)  {
3205                                 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3206                                 gtk_widget_show (GTK_WIDGET(inf_note));
3207                         }
3208                         
3209                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3210                         modest_mail_operation_xfer_folder (mail_op, 
3211                                                            src_folder,
3212                                                            folder_store,
3213                                                            delete,
3214                                                            destroy_information_note,
3215                                                            inf_note);
3216                 }
3217
3218                 /* Free */
3219                 if (data != NULL) 
3220                         g_object_unref (data);
3221                 if (src_folder != NULL) 
3222                         g_object_unref (src_folder);
3223                 if (folder_store != NULL) 
3224                         g_object_unref (folder_store);
3225         }
3226 }
3227
3228
3229 void
3230 modest_ui_actions_on_select_all (GtkAction *action,
3231                                  ModestWindow *window)
3232 {
3233         GtkWidget *focused_widget;
3234
3235         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3236         if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3237                 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3238         } else if (GTK_IS_LABEL (focused_widget)) {
3239                 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3240         } else if (GTK_IS_EDITABLE (focused_widget)) {
3241                 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3242         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3243                 GtkTextBuffer *buffer;
3244                 GtkTextIter start, end;
3245
3246                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3247                 gtk_text_buffer_get_start_iter (buffer, &start);
3248                 gtk_text_buffer_get_end_iter (buffer, &end);
3249                 gtk_text_buffer_select_range (buffer, &start, &end);
3250         } else if (GTK_IS_HTML (focused_widget)) {
3251                 gtk_html_select_all (GTK_HTML (focused_widget));
3252         } else if (MODEST_IS_MAIN_WINDOW (window)) {
3253                 GtkWidget *header_view = focused_widget;
3254                 GtkTreeSelection *selection = NULL;
3255                 
3256                 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3257                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3258                                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3259                 }
3260                                 
3261                 /* Disable window dimming management */
3262                 modest_window_disable_dimming (MODEST_WINDOW(window));
3263                 
3264                 /* Select all messages */
3265                 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3266                 gtk_tree_selection_select_all (selection);
3267
3268                 /* Set focuse on header view */
3269                 gtk_widget_grab_focus (header_view);
3270
3271
3272                 /* Enable window dimming management */
3273                 modest_window_enable_dimming (MODEST_WINDOW(window));
3274                 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3275         }
3276
3277 }
3278
3279 void
3280 modest_ui_actions_on_mark_as_read (GtkAction *action,
3281                                    ModestWindow *window)
3282 {       
3283         g_return_if_fail (MODEST_IS_WINDOW(window));
3284                 
3285         /* Mark each header as read */
3286         do_headers_action (window, headers_action_mark_as_read, NULL);
3287 }
3288
3289 void
3290 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3291                                      ModestWindow *window)
3292 {       
3293         g_return_if_fail (MODEST_IS_WINDOW(window));
3294                 
3295         /* Mark each header as read */
3296         do_headers_action (window, headers_action_mark_as_unread, NULL);
3297 }
3298
3299 void
3300 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3301                                   GtkRadioAction *selected,
3302                                   ModestWindow *window)
3303 {
3304         gint value;
3305
3306         value = gtk_radio_action_get_current_value (selected);
3307         if (MODEST_IS_WINDOW (window)) {
3308                 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3309         }
3310 }
3311
3312 void     
3313 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3314                                                GtkRadioAction *selected,
3315                                                ModestWindow *window)
3316 {
3317         TnyHeaderFlags flags;
3318         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3319
3320         flags = gtk_radio_action_get_current_value (selected);
3321         modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3322 }
3323
3324 void     
3325 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3326                                                   GtkRadioAction *selected,
3327                                                   ModestWindow *window)
3328 {
3329         gint file_format;
3330
3331         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3332
3333         file_format = gtk_radio_action_get_current_value (selected);
3334         modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3335 }
3336
3337
3338 void     
3339 modest_ui_actions_on_zoom_plus (GtkAction *action,
3340                                 ModestWindow *window)
3341 {
3342         g_return_if_fail (MODEST_IS_WINDOW (window));
3343
3344         modest_window_zoom_plus (MODEST_WINDOW (window));
3345 }
3346
3347 void     
3348 modest_ui_actions_on_zoom_minus (GtkAction *action,
3349                                  ModestWindow *window)
3350 {
3351         g_return_if_fail (MODEST_IS_WINDOW (window));
3352
3353         modest_window_zoom_minus (MODEST_WINDOW (window));
3354 }
3355
3356 void     
3357 modest_ui_actions_on_toggle_fullscreen    (GtkToggleAction *toggle,
3358                                            ModestWindow *window)
3359 {
3360         ModestWindowMgr *mgr;
3361         gboolean fullscreen, active;
3362         g_return_if_fail (MODEST_IS_WINDOW (window));
3363
3364         mgr = modest_runtime_get_window_mgr ();
3365
3366         active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3367         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3368
3369         if (active != fullscreen) {
3370                 modest_window_mgr_set_fullscreen_mode (mgr, active);
3371                 gtk_window_present (GTK_WINDOW (window));
3372         }
3373 }
3374
3375 void
3376 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3377                                         ModestWindow *window)
3378 {
3379         ModestWindowMgr *mgr;
3380         gboolean fullscreen;
3381
3382         g_return_if_fail (MODEST_IS_WINDOW (window));
3383
3384         mgr = modest_runtime_get_window_mgr ();
3385         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3386         modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3387
3388         gtk_window_present (GTK_WINDOW (window));
3389 }
3390
3391 /* 
3392  * Used by modest_ui_actions_on_details to call do_headers_action 
3393  */
3394 static void
3395 headers_action_show_details (TnyHeader *header, 
3396                              ModestWindow *window,
3397                              gpointer user_data)
3398
3399 {
3400         GtkWidget *dialog;
3401         
3402         /* Create dialog */
3403         dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3404
3405         /* Run dialog */
3406         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3407         gtk_widget_show_all (dialog);
3408         gtk_dialog_run (GTK_DIALOG (dialog));
3409
3410         gtk_widget_destroy (dialog);
3411 }
3412
3413 /*
3414  * Show the folder details in a ModestDetailsDialog widget
3415  */
3416 static void
3417 show_folder_details (TnyFolder *folder, 
3418                      GtkWindow *window)
3419 {
3420         GtkWidget *dialog;
3421         
3422         /* Create dialog */
3423         dialog = modest_details_dialog_new_with_folder (window, folder);
3424
3425         /* Run dialog */
3426         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3427         gtk_widget_show_all (dialog);
3428         gtk_dialog_run (GTK_DIALOG (dialog));
3429
3430         gtk_widget_destroy (dialog);
3431 }
3432
3433 /*
3434  * Show the header details in a ModestDetailsDialog widget
3435  */
3436 void     
3437 modest_ui_actions_on_details (GtkAction *action, 
3438                               ModestWindow *win)
3439 {
3440         TnyList * headers_list;
3441         TnyIterator *iter;
3442         TnyHeader *header;              
3443
3444         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3445                 TnyMsg *msg;
3446
3447                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3448                 if (!msg)
3449                         return;
3450                 g_object_unref (msg);           
3451
3452                 headers_list = get_selected_headers (win);
3453                 if (!headers_list)
3454                         return;
3455
3456                 iter = tny_list_create_iterator (headers_list);
3457
3458                 header = TNY_HEADER (tny_iterator_get_current (iter));
3459                 if (header) {
3460                         headers_action_show_details (header, win, NULL);
3461                         g_object_unref (header);
3462                 }
3463
3464                 g_object_unref (iter);
3465                 g_object_unref (headers_list);
3466
3467         } else if (MODEST_IS_MAIN_WINDOW (win)) {
3468                 GtkWidget *folder_view, *header_view;
3469
3470                 /* Check which widget has the focus */
3471                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3472                                                                     MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3473                 if (gtk_widget_is_focus (folder_view)) {
3474                         TnyFolderStore *folder_store
3475                                 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3476                         if (!folder_store) {
3477                                 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3478                                 return; 
3479                         }
3480                         /* Show only when it's a folder */
3481                         /* This function should not be called for account items, 
3482                          * because we dim the menu item for them. */
3483                         if (TNY_IS_FOLDER (folder_store)) {
3484                                 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3485                         }
3486
3487                         g_object_unref (folder_store);
3488
3489                 } else {
3490                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3491                                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3492                         /* Show details of each header */
3493                         do_headers_action (win, headers_action_show_details, header_view);
3494                 }
3495         }
3496 }
3497
3498 void     
3499 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3500                                      ModestMsgEditWindow *window)
3501 {
3502         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3503
3504         modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3505 }
3506
3507 void     
3508 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3509                                       ModestMsgEditWindow *window)
3510 {
3511         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3512
3513         modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3514 }
3515
3516 void
3517 modest_ui_actions_toggle_folders_view (GtkAction *action, 
3518                                        ModestMainWindow *main_window)
3519 {
3520         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3521
3522         if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3523                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3524         else
3525                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3526 }
3527
3528 void 
3529 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle, 
3530                                      ModestWindow *window)
3531 {
3532         gboolean active, fullscreen = FALSE;
3533         ModestWindowMgr *mgr;
3534
3535         active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3536
3537         /* Check if we want to toggle the toolbar vuew in fullscreen
3538            or normal mode */
3539         if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)), 
3540                      "ViewShowToolbarFullScreen")) {
3541                 fullscreen = TRUE;
3542         }
3543
3544         /* Toggle toolbar */
3545         mgr = modest_runtime_get_window_mgr ();
3546         modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3547 }
3548
3549 void     
3550 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3551                                            ModestMsgEditWindow *window)
3552 {
3553         modest_msg_edit_window_select_font (window);
3554 }
3555
3556 void
3557 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3558                                                   const gchar *display_name,
3559                                                   GtkWindow *window)
3560 {
3561         /* Do not change the application name if the widget has not
3562            the focus. This callback could be called even if the folder
3563            view has not the focus, because the handled signal could be
3564            emitted when the folder view is redrawn */
3565         if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3566                 if (display_name)
3567                         gtk_window_set_title (window, display_name);
3568                 else
3569                         gtk_window_set_title (window, " ");
3570         }
3571 }
3572
3573 void
3574 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3575 {
3576         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3577         modest_msg_edit_window_select_contacts (window);
3578 }
3579
3580 void
3581 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3582 {
3583         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3584         modest_msg_edit_window_check_names (window, FALSE);
3585 }
3586
3587 static void
3588 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3589 {
3590         modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3591                                          GTK_WIDGET (user_data));
3592 }
3593
3594 /*
3595  * This function is used to track changes in the selection of the
3596  * folder view that is inside the "move to" dialog to enable/disable
3597  * the OK button because we do not want the user to select a disallowed
3598  * destination for a folder.
3599  * The user also not desired to be able to use NEW button on items where
3600  * folder creation is not possibel.
3601  */
3602 static void
3603 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3604                                             TnyFolderStore *folder_store,
3605                                             gboolean selected,
3606                                             gpointer user_data)
3607 {
3608         GtkWidget *dialog = NULL;
3609         GtkWidget *ok_button = NULL, *new_button = NULL;
3610         GList *children = NULL;
3611         gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3612         gboolean moving_folder = FALSE;
3613         gboolean is_local_account = TRUE;
3614         GtkWidget *folder_view = NULL;
3615         ModestTnyFolderRules rules;
3616
3617         if (!selected)
3618                 return;
3619
3620         /* Get the OK button */
3621         dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3622         if (!dialog)
3623                 return;
3624
3625         children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3626         ok_button = GTK_WIDGET (children->next->next->data);
3627         new_button = GTK_WIDGET (children->next->data);
3628         g_list_free (children);
3629
3630         /* check if folder_store is an remote account */
3631         if (TNY_IS_ACCOUNT (folder_store)) {
3632                 TnyAccount *local_account = NULL;
3633                 ModestTnyAccountStore *account_store = NULL;
3634
3635                 account_store = modest_runtime_get_account_store ();
3636                 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3637
3638                 if ((gpointer) local_account != (gpointer) folder_store) {
3639                         is_local_account = FALSE;
3640                         /* New button should be dimmed on remote
3641                            account root */
3642                         new_sensitive = FALSE;
3643                 }
3644                 g_object_unref (local_account);
3645         }
3646
3647         /* Check the target folder rules */
3648         if (TNY_IS_FOLDER (folder_store)) {
3649                 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3650                 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3651                         ok_sensitive = FALSE;
3652                         new_sensitive = FALSE;
3653                         goto end;
3654                 }
3655         }
3656
3657         /* Check if we're moving a folder */
3658         if (MODEST_IS_MAIN_WINDOW (user_data)) {
3659                 /* Get the widgets */
3660                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3661                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3662                 if (gtk_widget_is_focus (folder_view))
3663                         moving_folder = TRUE;
3664         }
3665
3666         if (moving_folder) {
3667                 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3668
3669                 /* Get the folder to move */
3670                 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3671                 
3672                 /* Check that we're not moving to the same folder */
3673                 if (TNY_IS_FOLDER (moved_folder)) {
3674                         parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3675                         if (parent == folder_store)
3676                                 ok_sensitive = FALSE;
3677                         g_object_unref (parent);
3678                 } 
3679
3680                 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3681                         /* Do not allow to move to an account unless it's the
3682                            local folders account */
3683                         if (!is_local_account)
3684                                 ok_sensitive = FALSE;
3685                 } 
3686
3687                 if (ok_sensitive && (moved_folder == folder_store)) {
3688                         /* Do not allow to move to itself */
3689                         ok_sensitive = FALSE;
3690                 }
3691                 g_object_unref (moved_folder);
3692         } else {
3693                 TnyHeader *header = NULL;
3694                 TnyFolder *src_folder = NULL;
3695
3696                 /* Moving a message */
3697                 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3698                         header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3699                         src_folder = tny_header_get_folder (header);
3700                         g_object_unref (header);
3701                 } else {
3702                         src_folder = 
3703                                 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3704                 }
3705
3706                 /* Do not allow to move the msg to the same folder */
3707                 /* Do not allow to move the msg to an account */
3708                 if ((gpointer) src_folder == (gpointer) folder_store ||
3709                     TNY_IS_ACCOUNT (folder_store))
3710                         ok_sensitive = FALSE;
3711                 g_object_unref (src_folder);
3712         }
3713
3714  end:
3715         /* Set sensitivity of the OK button */
3716         gtk_widget_set_sensitive (ok_button, ok_sensitive);
3717         /* Set sensitivity of the NEW button */
3718         gtk_widget_set_sensitive (new_button, new_sensitive);
3719 }
3720
3721 static GtkWidget*
3722 create_move_to_dialog (GtkWindow *win,
3723                        GtkWidget *folder_view,
3724                        GtkWidget **tree_view)
3725 {
3726         GtkWidget *dialog, *scroll;
3727         GtkWidget *new_button;
3728
3729         dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3730                                               GTK_WINDOW (win),
3731                                               GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3732                                               NULL);
3733
3734         gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3735         /* We do this manually so GTK+ does not associate a response ID for
3736          * the button. */
3737         new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3738         gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3739         gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3740
3741         /* Create scrolled window */
3742         scroll = gtk_scrolled_window_new (NULL, NULL);
3743         gtk_scrolled_window_set_policy  (GTK_SCROLLED_WINDOW (scroll),
3744                                          GTK_POLICY_AUTOMATIC,
3745                                          GTK_POLICY_AUTOMATIC);
3746
3747         /* Create folder view */
3748         *tree_view = modest_platform_create_folder_view (NULL);
3749
3750         /* Track changes in the selection to
3751          * disable the OK button whenever "Move to" is not possible
3752          * disbale NEW button whenever New is not possible */
3753         g_signal_connect (*tree_view,
3754                           "folder_selection_changed",
3755                           G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3756                           win);
3757
3758         /* Listen to clicks on New button */
3759         g_signal_connect (G_OBJECT (new_button), 
3760                           "clicked", 
3761                           G_CALLBACK(create_move_to_dialog_on_new_folder), 
3762                           *tree_view);
3763
3764         /* It could happen that we're trying to move a message from a
3765            window (msg window for example) after the main window was
3766            closed, so we can not just get the model of the folder
3767            view */
3768         if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3769                 const gchar *visible_id = NULL;
3770
3771                 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view), 
3772                                                MODEST_FOLDER_VIEW(*tree_view));
3773
3774                 visible_id = 
3775                         modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3776
3777                 /* Show the same account than the one that is shown in the main window */
3778                 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view), 
3779                                                                              visible_id);
3780         } else {
3781                 const gchar *active_account_name = NULL;
3782                 ModestAccountMgr *mgr = NULL;
3783                 ModestAccountData *acc_data = NULL;
3784
3785                 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view), 
3786                                                  TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3787
3788                 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3789                 mgr = modest_runtime_get_account_mgr ();
3790                 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3791
3792                 /* Set the new visible & active account */
3793                 if (acc_data && acc_data->store_account) { 
3794                         modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3795                                                                                      acc_data->store_account->account_name);
3796                         modest_account_mgr_free_account_data (mgr, acc_data);
3797                 }
3798         }
3799
3800         /* Hide special folders */
3801         modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3802         
3803         gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3804
3805         /* Add scroll to dialog */
3806         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), 
3807                             scroll, TRUE, TRUE, 0);
3808
3809         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3810         gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3811
3812         return dialog;
3813 }
3814
3815 /*
3816  * Returns TRUE if at least one of the headers of the list belongs to
3817  * a message that has been fully retrieved.
3818  */
3819 #if 0 /* no longer in use. delete in 2007.10 */
3820 static gboolean
3821 has_retrieved_msgs (TnyList *list)
3822 {
3823         TnyIterator *iter;
3824         gboolean found = FALSE;
3825
3826         iter = tny_list_create_iterator (list);
3827         while (!tny_iterator_is_done (iter) && !found) {
3828                 TnyHeader *header;
3829                 TnyHeaderFlags flags = 0;
3830
3831                 header = TNY_HEADER (tny_iterator_get_current (iter));
3832                 if (header) {
3833                         flags = tny_header_get_flags (header);
3834                         if (flags & TNY_HEADER_FLAG_CACHED)
3835 /*                      if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3836                                 found = TRUE;
3837
3838                         g_object_unref (header);
3839                 }
3840
3841                 if (!found)
3842                         tny_iterator_next (iter);
3843         }
3844         g_object_unref (iter);
3845
3846         return found;
3847 }
3848 #endif /* 0 */
3849
3850
3851 /*
3852  * Shows a confirmation dialog to the user when we're moving messages
3853  * from a remote server to the local storage. Returns the dialog
3854  * response. If it's other kind of movement then it always returns
3855  * GTK_RESPONSE_OK
3856  *
3857  * This one is used by the next functions:
3858  *      modest_ui_actions_on_paste                      - commented out
3859  *      drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3860  */
3861 gint
3862 modest_ui_actions_msgs_move_to_confirmation (GtkWindow *win,
3863                                              TnyFolder *dest_folder,
3864                                              gboolean delete,
3865                                              TnyList *headers)
3866 {
3867         gint response = GTK_RESPONSE_OK;
3868
3869         /* return with OK if the destination is a remote folder */
3870         if (modest_tny_folder_is_remote_folder (dest_folder))
3871                 return GTK_RESPONSE_OK;
3872
3873         TnyFolder *src_folder = NULL;
3874         TnyIterator *iter = NULL;
3875         TnyHeader *header = NULL;
3876
3877         /* Get source folder */
3878         iter = tny_list_create_iterator (headers);
3879         header = TNY_HEADER (tny_iterator_get_current (iter));
3880         if (header) {
3881                 src_folder = tny_header_get_folder (header);
3882                 g_object_unref (header);
3883         }
3884         g_object_unref (iter);
3885
3886         /* if no src_folder, message may be an attahcment */
3887         if (src_folder == NULL) 
3888                 return GTK_RESPONSE_CANCEL;
3889
3890         /* If the source is a local or MMC folder */
3891         if (!modest_tny_folder_is_remote_folder (src_folder)) {
3892                 g_object_unref (src_folder);
3893                 return GTK_RESPONSE_OK;
3894         }
3895         g_object_unref (src_folder);
3896
3897         /* now if offline we ask the user */
3898         if(connect_to_get_msg(  GTK_WINDOW (win),
3899                                         tny_list_get_length (headers)))
3900                 response = GTK_RESPONSE_OK;
3901         else
3902                 response = GTK_RESPONSE_CANCEL;
3903
3904         return response;
3905 }
3906
3907
3908
3909 static void
3910 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
3911 {
3912         MoveToHelper *helper = (MoveToHelper *) user_data;
3913
3914         /* Note that the operation could have failed, in that case do
3915            nothing */
3916         if (modest_mail_operation_get_status (mail_op) == 
3917             MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
3918
3919                 GObject *object = modest_mail_operation_get_source (mail_op);
3920                 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
3921                         ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
3922
3923                         if (!modest_msg_view_window_select_next_message (self))
3924                                 if (!modest_msg_view_window_select_previous_message (self))
3925                                         /* No more messages to view, so close this window */
3926                                         modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3927                 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
3928                         GtkWidget *header_view;
3929                         GtkTreePath *path;
3930                         GtkTreeSelection *sel;
3931
3932                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
3933                                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3934                         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
3935                         path = gtk_tree_row_reference_get_path (helper->reference);
3936                         gtk_tree_selection_select_path (sel, path);
3937                         gtk_tree_path_free (path);
3938                 }
3939                 g_object_unref (object);
3940         }
3941
3942         /* Close the "Pasting" information banner */
3943         gtk_widget_destroy (GTK_WIDGET(helper->banner));
3944         if (helper->reference != NULL)
3945                 gtk_tree_row_reference_free (helper->reference);
3946         g_free (helper);
3947 }
3948
3949 void
3950 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op, 
3951                                              gpointer user_data)
3952 {
3953         ModestWindow *main_window = NULL;
3954         GtkWidget *folder_view = NULL;
3955         GObject *win = modest_mail_operation_get_source (mail_op);
3956         const GError *error = NULL;
3957         const gchar *message = NULL;
3958         
3959         /* Get error message */
3960         error = modest_mail_operation_get_error (mail_op);
3961         if (error != NULL && error->message != NULL) {
3962                 message = error->message;
3963         } else {
3964                 message = _("mail_in_ui_folder_move_target_error");
3965         }
3966         
3967         /* Disable next automatic folder selection */
3968         main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
3969         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
3970                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW); 
3971         modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
3972         
3973         if (user_data && TNY_IS_FOLDER (user_data)) {
3974                 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), 
3975                                                   TNY_FOLDER (user_data), FALSE);
3976         }
3977
3978         /* Show notification dialog */
3979         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3980         g_object_unref (win);
3981 }
3982
3983 void
3984 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op, 
3985                                               gpointer user_data)
3986 {
3987         GObject *win = modest_mail_operation_get_source (mail_op);
3988         const GError *error = modest_mail_operation_get_error (mail_op);
3989
3990         g_return_if_fail (error != NULL);
3991         if (error->message != NULL)             
3992                 g_printerr ("modest: %s\n", error->message);
3993         else
3994                 g_printerr ("modest: unkonw error on send&receive operation");
3995
3996         /* Show error message */
3997 /*      if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3998 /*              modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3999 /*                                                      _CS("sfil_ib_unable_to_receive")); */
4000 /*      else  */
4001 /*              modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4002 /*                                                      _CS("sfil_ib_unable_to_send")); */
4003         g_object_unref (win);
4004 }
4005
4006 static void
4007 open_msg_for_purge_cb (ModestMailOperation *mail_op, 
4008                        TnyHeader *header, 
4009                        TnyMsg *msg, 
4010                        gpointer user_data)
4011 {
4012         TnyList *parts;
4013         TnyIterator *iter;
4014         gint pending_purges = 0;
4015         gboolean some_purged = FALSE;
4016         ModestWindow *win = MODEST_WINDOW (user_data);
4017         ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4018
4019         /* If there was any error */
4020         if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4021                 modest_window_mgr_unregister_header (mgr, header);
4022                 return;
4023         }
4024
4025         /* Once the message has been retrieved for purging, we check if
4026          * it's all ok for purging */
4027
4028         parts = tny_simple_list_new ();
4029         tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4030         iter = tny_list_create_iterator (parts);
4031
4032         while (!tny_iterator_is_done (iter)) {
4033                 TnyMimePart *part;
4034                 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4035                 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4036                         if (tny_mime_part_is_purged (part))
4037                                 some_purged = TRUE;
4038                         else
4039                                 pending_purges++;
4040                 }
4041
4042                 if (part)
4043                         g_object_unref (part);
4044
4045                 tny_iterator_next (iter);
4046         }
4047         g_object_unref (iter);
4048         
4049
4050         if (pending_purges>0) {
4051                 gint response;
4052                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4053
4054                 if (response == GTK_RESPONSE_OK) {
4055                         modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4056                         iter = tny_list_create_iterator (parts);
4057                         while (!tny_iterator_is_done (iter)) {
4058                                 TnyMimePart *part;
4059                                 
4060                                 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4061                                 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4062                                         tny_mime_part_set_purged (part);
4063
4064                                 if (part)
4065                                         g_object_unref (part);
4066
4067                                 tny_iterator_next (iter);
4068                         }
4069                         
4070                         tny_msg_rewrite_cache (msg);
4071                 }
4072         } else {
4073                 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
4074         }
4075         g_object_unref (iter);
4076
4077         modest_window_mgr_unregister_header (mgr, header);
4078
4079         g_object_unref (parts);
4080 }
4081
4082 static void
4083 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4084                                                      ModestMainWindow *win)
4085 {
4086         GtkWidget *header_view;
4087         TnyList *header_list;
4088         TnyIterator *iter;
4089         TnyHeader *header;
4090         TnyHeaderFlags flags;
4091         ModestWindow *msg_view_window =  NULL;
4092         gboolean found;
4093
4094         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4095
4096         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4097                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4098
4099         header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4100
4101         if (tny_list_get_length (header_list) == 1) {
4102                 iter = tny_list_create_iterator (header_list);
4103                 header = TNY_HEADER (tny_iterator_get_current (iter));
4104                 g_object_unref (iter);
4105         } else {
4106                 return;
4107         }
4108
4109         found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4110                                                           header, &msg_view_window);
4111         flags = tny_header_get_flags (header);
4112         if (!(flags & TNY_HEADER_FLAG_CACHED))
4113                 return;
4114         if (found) {
4115                 if (msg_view_window != NULL) 
4116                         modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4117                 else {
4118                         /* do nothing; uid was registered before, so window is probably on it's way */
4119                         g_warning ("debug: header %p has already been registered", header);
4120                 }
4121         } else {
4122                 ModestMailOperation *mail_op = NULL;
4123                 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
4124                 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
4125                                                                          modest_ui_actions_get_msgs_full_error_handler,
4126                                                                          NULL);
4127                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4128                 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4129                 
4130                 g_object_unref (mail_op);
4131         }
4132         if (header)
4133                 g_object_unref (header);
4134         if (header_list)
4135                 g_object_unref (header_list);
4136 }
4137
4138 /**
4139  * Utility function that transfer messages from both the main window
4140  * and the msg view window when using the "Move to" dialog
4141  */
4142 static void
4143 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4144                                               ModestWindow *win)
4145 {
4146         TnyList *headers = NULL;
4147         TnyAccount *dst_account = NULL;
4148         const gchar *proto_str = NULL;
4149         gboolean dst_is_pop = FALSE;
4150
4151         if (!TNY_IS_FOLDER (dst_folder)) {
4152                 modest_platform_information_banner (GTK_WIDGET (win),
4153                                                     NULL,
4154                                                     _CS("ckdg_ib_unable_to_move_to_current_location"));
4155                 return;
4156         }
4157
4158         dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4159         proto_str = tny_account_get_proto (dst_account);
4160
4161         /* tinymail will return NULL for local folders it seems */
4162         dst_is_pop = proto_str &&
4163                 (modest_protocol_info_get_transport_store_protocol (proto_str) == 
4164                  MODEST_PROTOCOL_STORE_POP);
4165
4166         g_object_unref (dst_account);
4167
4168         /* Get selected headers */
4169         headers = get_selected_headers (MODEST_WINDOW (win));
4170
4171         if (dst_is_pop) {
4172                 modest_platform_information_banner (GTK_WIDGET (win),
4173                                                     NULL,
4174                                                     ngettext("mail_in_ui_folder_move_target_error",
4175                                                              "mail_in_ui_folder_move_targets_error",
4176                                                              tny_list_get_length (headers)));
4177                 g_object_unref (headers);
4178                 return;
4179         }
4180
4181         MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4182         helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4183                                                            _CS("ckct_nw_pasting"));
4184         if (helper->banner != NULL)  {
4185                 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4186                 gtk_widget_show (GTK_WIDGET(helper->banner));
4187         }
4188
4189         if (MODEST_IS_MAIN_WINDOW (win)) {
4190                 GtkWidget *header_view = 
4191                         modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
4192                                                              MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4193                 helper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
4194         }
4195
4196         ModestMailOperation *mail_op = 
4197                 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4198                                                                modest_ui_actions_move_folder_error_handler,
4199                                                                NULL);
4200         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
4201                                          mail_op);
4202
4203         modest_mail_operation_xfer_msgs (mail_op, 
4204                                          headers,
4205                                          TNY_FOLDER (dst_folder),
4206                                          TRUE,
4207                                          move_to_cb,
4208                                          helper);
4209
4210         g_object_unref (G_OBJECT (mail_op));
4211         g_object_unref (headers);
4212 }
4213
4214 /*
4215  * UI handler for the "Move to" action when invoked from the
4216  * ModestMainWindow
4217  */
4218 static void 
4219 modest_ui_actions_on_main_window_move_to (GtkAction *action, 
4220                                           GtkWidget *folder_view,
4221                                           TnyFolderStore *dst_folder,
4222                                           ModestMainWindow *win)
4223 {
4224         ModestHeaderView *header_view = NULL;
4225         ModestMailOperation *mail_op = NULL;
4226         TnyFolderStore *src_folder;
4227         gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4228
4229         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4230
4231         /* Get the source folder */
4232         src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4233
4234         /* Get header view */
4235         header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4236
4237         /* Get folder or messages to transfer */
4238         if (gtk_widget_is_focus (folder_view)) {
4239                 GtkTreeSelection *sel;
4240                 gboolean do_xfer = TRUE;
4241
4242                 /* Allow only to transfer folders to the local root folder */
4243                 if (TNY_IS_ACCOUNT (dst_folder) && 
4244                     !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4245                         do_xfer = FALSE;
4246                 } else if (!TNY_IS_FOLDER (src_folder)) {
4247                         g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4248                         do_xfer = FALSE;
4249                 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4250                         guint num_headers = tny_folder_get_all_count(TNY_FOLDER(src_folder));
4251                         if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4252                                 do_xfer = FALSE;
4253                         }
4254                 }
4255
4256                 if (do_xfer) {
4257                         MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4258                         helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4259                                                                            _CS("ckct_nw_pasting"));
4260                         if (helper->banner != NULL)  {
4261                                 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4262                                 gtk_widget_show (GTK_WIDGET(helper->banner));
4263                         }
4264                         /* Clean folder on header view before moving it */
4265                         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4266                         gtk_tree_selection_unselect_all (sel);
4267
4268                         mail_op =
4269                           modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4270                                                                          modest_ui_actions_move_folder_error_handler,
4271                                                                          src_folder);
4272                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4273                                                          mail_op);
4274
4275                         /* Select *after* the changes */
4276                         /* TODO: this function hangs UI after transfer */ 
4277 /*                      modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4278 /*                                                        TNY_FOLDER (src_folder), TRUE); */
4279                         
4280                         modest_mail_operation_xfer_folder (mail_op,
4281                                                            TNY_FOLDER (src_folder),
4282                                                            dst_folder,
4283                                                            TRUE, 
4284                                                            move_to_cb, 
4285                                                            helper);
4286                         /* Unref mail operation */
4287                         g_object_unref (G_OBJECT (mail_op));
4288                 }
4289         } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4290                 gboolean do_xfer = TRUE;
4291                 /* Ask for confirmation if the source folder is remote and we're not connected */
4292                 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4293                         TnyList *headers = modest_header_view_get_selected_headers(header_view);
4294                         if (!msgs_already_deleted_from_server(headers, src_folder)) {
4295                                 guint num_headers = tny_list_get_length(headers);
4296                                 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4297                                         do_xfer = FALSE;
4298                                 }
4299                         }
4300                         g_object_unref(headers);
4301                 }
4302                 if (do_xfer) /* Transfer messages */
4303                         modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4304         }
4305
4306     if (src_folder)
4307         g_object_unref (src_folder);
4308 }
4309
4310
4311 /*
4312  * UI handler for the "Move to" action when invoked from the
4313  * ModestMsgViewWindow
4314  */
4315 static void 
4316 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action, 
4317                                               TnyFolderStore *dst_folder,
4318                                               ModestMsgViewWindow *win)
4319 {
4320         TnyHeader *header = NULL;
4321         TnyFolderStore *src_folder;
4322
4323         /* Create header list */
4324         header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));              
4325         src_folder = TNY_FOLDER_STORE(tny_header_get_folder(header));
4326         g_object_unref (header);
4327
4328         /* Transfer the message if online or confirmed by the user */
4329         if (tny_device_is_online (modest_runtime_get_device()) || remote_folder_is_pop(src_folder) ||
4330             (modest_platform_is_network_folderstore(src_folder) && connect_to_get_msg(GTK_WINDOW(win), 1))) {
4331                 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4332         }
4333
4334         g_object_unref (src_folder);
4335 }
4336
4337 void 
4338 modest_ui_actions_on_move_to (GtkAction *action, 
4339                               ModestWindow *win)
4340 {
4341         GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4342         gint result = 0;
4343         TnyFolderStore *dst_folder = NULL;
4344         ModestMainWindow *main_window;
4345
4346         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4347                           MODEST_IS_MSG_VIEW_WINDOW (win));
4348
4349         /* Get the main window if exists */
4350         if (MODEST_IS_MAIN_WINDOW (win))
4351                 main_window = MODEST_MAIN_WINDOW (win);
4352         else
4353                 main_window = 
4354                         MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4355
4356         /* Get the folder view widget if exists */
4357         if (main_window)
4358                 folder_view = modest_main_window_get_child_widget (main_window,
4359                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4360         else
4361                 folder_view = NULL;
4362
4363         /* Create and run the dialog */
4364         dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4365         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4366         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4367         result = gtk_dialog_run (GTK_DIALOG(dialog));
4368         g_object_ref (tree_view);
4369         gtk_widget_destroy (dialog);
4370
4371         if (result != GTK_RESPONSE_ACCEPT)
4372                 return;
4373
4374         dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4375         /* Do window specific stuff */
4376         if (MODEST_IS_MAIN_WINDOW (win)) {
4377                 modest_ui_actions_on_main_window_move_to (action,
4378                                                           folder_view,
4379                                                           dst_folder,
4380                                                           MODEST_MAIN_WINDOW (win));
4381         } else {
4382                 modest_ui_actions_on_msg_view_window_move_to (action,
4383                                                               dst_folder,
4384                                                               MODEST_MSG_VIEW_WINDOW (win));
4385         }
4386
4387         if (dst_folder)
4388                 g_object_unref (dst_folder);
4389 }
4390
4391 /*
4392  * Calls #HeadersFunc for each header already selected in the main
4393  * window or the message currently being shown in the msg view window
4394  */
4395 static void
4396 do_headers_action (ModestWindow *win, 
4397                    HeadersFunc func,
4398                    gpointer user_data)
4399 {
4400         TnyList *headers_list = NULL;
4401         TnyIterator *iter = NULL;
4402         TnyHeader *header = NULL;
4403         TnyFolder *folder = NULL;
4404
4405         /* Get headers */
4406         headers_list = get_selected_headers (win);
4407         if (!headers_list)
4408                 return;
4409
4410         /* Get the folder */
4411         iter = tny_list_create_iterator (headers_list);
4412         header = TNY_HEADER (tny_iterator_get_current (iter));
4413         if (header) {
4414                 folder = tny_header_get_folder (header);
4415                 g_object_unref (header);
4416         }
4417
4418         /* Call the function for each header */
4419         while (!tny_iterator_is_done (iter)) {
4420                 header = TNY_HEADER (tny_iterator_get_current (iter));
4421                 func (header, win, user_data);
4422                 g_object_unref (header);
4423                 tny_iterator_next (iter);
4424         }
4425
4426         /* Trick: do a poke status in order to speed up the signaling
4427            of observers */
4428         tny_folder_poke_status (folder);
4429
4430         /* Frees */
4431         g_object_unref (folder);
4432         g_object_unref (iter);
4433         g_object_unref (headers_list);
4434 }
4435
4436 void 
4437 modest_ui_actions_view_attachment (GtkAction *action,
4438                                    ModestWindow *window)
4439 {
4440         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4441                 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4442         } else {
4443                 /* not supported window for this action */
4444                 g_return_if_reached ();
4445         }
4446 }
4447
4448 void
4449 modest_ui_actions_save_attachments (GtkAction *action,
4450                                     ModestWindow *window)
4451 {
4452         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4453                 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4454         } else {
4455                 /* not supported window for this action */
4456                 g_return_if_reached ();
4457         }
4458 }
4459
4460 void
4461 modest_ui_actions_remove_attachments (GtkAction *action,
4462                                       ModestWindow *window)
4463 {
4464         if (MODEST_IS_MAIN_WINDOW (window)) {
4465                 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4466         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4467                 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4468         } else {
4469                 /* not supported window for this action */
4470                 g_return_if_reached ();
4471         }
4472 }
4473
4474 void 
4475 modest_ui_actions_on_settings (GtkAction *action, 
4476                                ModestWindow *win)
4477 {
4478         GtkWidget *dialog;
4479
4480         dialog = modest_platform_get_global_settings_dialog ();
4481         gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4482         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4483         gtk_widget_show_all (dialog);
4484
4485         gtk_dialog_run (GTK_DIALOG (dialog));
4486
4487         gtk_widget_destroy (dialog);
4488 }
4489
4490 void 
4491 modest_ui_actions_on_help (GtkAction *action, 
4492                            ModestWindow *win)
4493 {
4494         const gchar *help_id = NULL;
4495
4496         if (MODEST_IS_MAIN_WINDOW (win)) {
4497                 GtkWidget *folder_view;
4498                 TnyFolderStore *folder_store;
4499                 
4500                 /* Get selected folder */
4501                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4502                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4503                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4504
4505                 /* Switch help_id */
4506                 if (TNY_IS_FOLDER (folder_store)) {
4507                         switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4508                         case TNY_FOLDER_TYPE_NORMAL:
4509                                 help_id = "applications_email_managefolders";
4510                                 break;
4511                         case TNY_FOLDER_TYPE_INBOX:
4512                                 help_id = "applications_email_inbox";
4513                                 break;
4514                         case TNY_FOLDER_TYPE_OUTBOX:
4515                                 help_id = "applications_email_outbox";
4516                                 break;
4517                         case TNY_FOLDER_TYPE_SENT:
4518                                 help_id = "applications_email_sent";
4519                                 break;
4520                         case TNY_FOLDER_TYPE_DRAFTS:
4521                                 help_id = "applications_email_drafts";
4522                                 break;
4523                         case TNY_FOLDER_TYPE_ARCHIVE:
4524                                 help_id = "applications_email_managefolders";
4525                                 break;
4526                         default:
4527                                 help_id = "applications_email_managefolders";
4528                         }
4529                 } else {
4530                         help_id = "applications_email_mainview";
4531                 }
4532                 g_object_unref (folder_store);
4533         } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4534                 help_id = "applications_email_viewer";
4535         } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4536                 help_id = "applications_email_editor";
4537
4538         modest_platform_show_help (GTK_WINDOW (win), help_id);
4539 }
4540
4541 void 
4542 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4543                                             ModestWindow *window)
4544 {
4545         ModestMailOperation *mail_op;
4546         TnyList *headers;
4547
4548         /* Get headers */
4549         headers = get_selected_headers (window);
4550         if (!headers)
4551                 return;
4552
4553         /* Create mail operation */
4554         mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (window),
4555                                                                  modest_ui_actions_get_msgs_full_error_handler, 
4556                                                                  NULL);
4557         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4558         modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4559
4560         /* Frees */
4561         g_object_unref (headers);
4562         g_object_unref (mail_op);
4563 }
4564
4565 void
4566 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4567                                           ModestWindow *window)
4568 {
4569         g_return_if_fail (MODEST_IS_WINDOW (window));
4570         
4571         /* Update dimmed */     
4572         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4573 }
4574
4575 void
4576 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4577                                           ModestWindow *window)
4578 {
4579         g_return_if_fail (MODEST_IS_WINDOW (window));
4580
4581         /* Update dimmed */     
4582         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4583 }
4584
4585 void
4586 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4587                                           ModestWindow *window)
4588 {
4589         g_return_if_fail (MODEST_IS_WINDOW (window));
4590
4591         /* Update dimmed */     
4592         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4593 }
4594
4595 void
4596 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4597                                             ModestWindow *window)
4598 {
4599         g_return_if_fail (MODEST_IS_WINDOW (window));
4600
4601         /* Update dimmed */     
4602         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4603 }
4604
4605 void
4606 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4607                                           ModestWindow *window)
4608 {
4609         g_return_if_fail (MODEST_IS_WINDOW (window));
4610
4611         /* Update dimmed */     
4612         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4613 }
4614
4615 void
4616 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4617                                           ModestWindow *window)
4618 {
4619         g_return_if_fail (MODEST_IS_WINDOW (window));
4620
4621         /* Update dimmed */     
4622         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4623 }
4624
4625 void
4626 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4627                                                  ModestWindow *window)
4628 {
4629         g_return_if_fail (MODEST_IS_WINDOW (window));
4630
4631         /* Update dimmed */     
4632         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4633 }
4634
4635 void
4636 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4637                                                      ModestWindow *window)
4638 {
4639         g_return_if_fail (MODEST_IS_WINDOW (window));
4640
4641         /* Update dimmed */     
4642         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4643 }
4644
4645 void
4646 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4647                                                      ModestWindow *window)
4648 {
4649         g_return_if_fail (MODEST_IS_WINDOW (window));
4650
4651         /* Update dimmed */     
4652         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4653 }
4654
4655 void
4656 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4657 {
4658         g_return_if_fail (MODEST_IS_WINDOW (window));
4659
4660         /* Update dimmed */     
4661         modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");  
4662 }
4663
4664 void
4665 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4666 {
4667         g_return_if_fail (MODEST_IS_WINDOW (window));
4668
4669         modest_platform_show_search_messages (GTK_WINDOW (window));
4670 }
4671
4672 void     
4673 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4674 {
4675         g_return_if_fail (MODEST_IS_WINDOW (win));
4676         modest_platform_show_addressbook (GTK_WINDOW (win));
4677 }
4678
4679
4680 void
4681 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4682                                           ModestWindow *window)
4683 {
4684         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4685
4686         modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4687 }
4688
4689 static void 
4690 on_send_receive_finished (ModestMailOperation  *mail_op, 
4691                            gpointer user_data)
4692 {
4693         /* Set send/receive operation finished */       
4694         modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW (user_data));      
4695 }
4696
4697
4698 void 
4699 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self, 
4700                                                 TnyHeader *header, 
4701                                                 TnyMsg *msg, 
4702                                                 GError *err, 
4703                                                 gpointer user_data)
4704 {
4705         const gchar* server_name = NULL;
4706         TnyTransportAccount *server_account;
4707         gchar *message = NULL;
4708
4709         /* Don't show anything if the user cancelled something */
4710         if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4711                 return;
4712
4713         /* Get the server name: */
4714         server_account = 
4715                 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4716         if (server_account) {
4717                 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4718                         
4719                 g_object_unref (server_account);
4720                 server_account = NULL;
4721         }
4722         
4723         g_return_if_fail (server_name);
4724
4725         /* Show the appropriate message text for the GError: */
4726         switch (err->code) {
4727         case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4728                 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4729                 break;
4730         case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4731                 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4732                 break;
4733         case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4734                 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4735                 break;
4736         case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4737                 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4738                 break;
4739         default:
4740                 g_return_if_reached ();
4741         }
4742         
4743         /* TODO if the username or the password where not defined we
4744            should show the Accounts Settings dialog or the Connection
4745            specific SMTP server window */
4746
4747         modest_platform_run_information_dialog (NULL, message);
4748         g_free (message);
4749 }
4750
4751 void
4752 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4753                                                 gchar *msg_id, 
4754                                                 guint status,
4755                                                 gpointer user_data)
4756 {
4757         ModestMainWindow *main_window = NULL;
4758         ModestWindowMgr *mgr = NULL;
4759         GtkWidget *folder_view = NULL, *header_view = NULL;
4760         TnyFolderStore *selected_folder = NULL;
4761         TnyFolderType folder_type;
4762
4763         mgr = modest_runtime_get_window_mgr ();
4764         main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
4765
4766         if (!main_window)
4767                 return;
4768
4769         /* Check if selected folder is OUTBOX */
4770         folder_view = modest_main_window_get_child_widget (main_window,
4771                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4772         header_view = modest_main_window_get_child_widget (main_window,
4773                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4774
4775         selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4776         if (!TNY_IS_FOLDER (selected_folder)) 
4777                 goto frees;
4778
4779         /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4780 #if GTK_CHECK_VERSION(2, 8, 0) 
4781         folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder)); 
4782         if (folder_type ==  TNY_FOLDER_TYPE_OUTBOX) {           
4783                 GtkTreeViewColumn *tree_column;
4784
4785                 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view), 
4786                                                         TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4787                 gtk_tree_view_column_queue_resize (tree_column);
4788         }
4789 #else
4790         gtk_widget_queue_draw (header_view);
4791 #endif          
4792         
4793         /* Free */
4794  frees:
4795         if (selected_folder != NULL)
4796                 g_object_unref (selected_folder);
4797 }