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