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