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