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