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