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