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