* Refactored "Move to" code in order to allow this call from the ModestMsgViewWindow
[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 <string.h>
36 #include <modest-runtime.h>
37 #include <modest-tny-folder.h>
38 #include <modest-tny-msg.h>
39 #include <modest-tny-account.h>
40 #include <modest-address-book.h>
41
42 #include "modest-ui-actions.h"
43
44 #include "modest-tny-platform-factory.h"
45 #include "modest-platform.h"
46
47 #include <widgets/modest-main-window.h>
48 #include <widgets/modest-msg-view-window.h>
49 #include <widgets/modest-account-view-window.h>
50 #include <widgets/modest-details-dialog.h>
51
52 #include "modest-account-mgr-helpers.h"
53 #include "modest-mail-operation.h"
54 #include "modest-text-utils.h"
55
56 #ifdef MODEST_HAVE_EASYSETUP
57 #include "easysetup/modest-easysetup-wizard.h"
58 #endif /*MODEST_HAVE_EASYSETUP*/
59
60 #include <modest-widget-memory.h>
61 #include <tny-error.h>
62 #include <tny-simple-list.h>
63 #include <tny-msg-view.h>
64 #include <tny-device.h>
65
66 typedef struct _GetMsgAsyncHelper {
67         ModestWindow *window;
68         TnyIterator *iter;
69         GFunc func;
70         gpointer user_data;
71 } GetMsgAsyncHelper;
72
73 typedef enum _ReplyForwardAction {
74         ACTION_REPLY,
75         ACTION_REPLY_TO_ALL,
76         ACTION_FORWARD
77 } ReplyForwardAction;
78
79 typedef struct _ReplyForwardHelper {
80 guint reply_forward_type;
81         ReplyForwardAction action;
82         gchar *account_name;
83 } ReplyForwardHelper;
84
85
86 static void     reply_forward_func     (gpointer data, gpointer user_data);
87 static void     read_msg_func          (gpointer data, gpointer user_data);
88 static void     get_msg_cb             (TnyFolder *folder, TnyMsg *msg, GError **err, 
89                                         gpointer user_data);
90 static void     reply_forward          (ReplyForwardAction action, ModestWindow *win);
91
92 static gchar*   ask_for_folder_name    (GtkWindow *parent_window, const gchar *title);
93
94
95 void   
96 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
97 {
98         GtkWidget *about;
99         const gchar *authors[] = {
100                 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
101                 NULL
102         };
103         about = gtk_about_dialog_new ();
104         gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
105         gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
106         gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
107                                         _("Copyright (c) 2006, Nokia Corporation\n"
108                                           "All rights reserved."));
109         gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
110                                        _("a modest e-mail client\n\n"
111                                          "design and implementation: Dirk-Jan C. Binnema\n"
112                                          "contributions from the fine people at KC and Ig\n"
113                                          "uses the tinymail email framework written by Philip van Hoof"));
114         gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
115         gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
116         
117         gtk_dialog_run (GTK_DIALOG (about));
118         gtk_widget_destroy(about);
119 }
120
121
122 static TnyList *
123 get_selected_headers (ModestWindow *win)
124 {
125         if (MODEST_IS_MAIN_WINDOW(win)) {
126                 GtkWidget *header_view;         
127                 
128                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
129                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
130                 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
131                 
132         } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
133                 /* for MsgViewWindows, we simply return a list with one element */
134                 TnyMsg *msg;
135                 TnyHeader *header;
136                 TnyList *list = NULL;
137                 
138                 msg  = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
139                 if (msg) {
140                         header = tny_msg_get_header (msg);
141                         list = tny_simple_list_new ();
142                         tny_list_prepend (list, G_OBJECT(header));
143                         g_object_unref (G_OBJECT(header));
144                 }
145                 return list;
146
147         } else
148                 return NULL;
149 }
150
151 void
152 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
153 {
154         TnyList *header_list;
155         TnyIterator *iter;
156
157         g_return_if_fail (MODEST_IS_WINDOW(win));
158                 
159         header_list = get_selected_headers (win);
160         
161         if (header_list) {
162                 iter = tny_list_create_iterator (header_list);
163                 do {
164                         TnyHeader *header;
165                         ModestMailOperation *mail_op;
166
167                         header = TNY_HEADER (tny_iterator_get_current (iter));
168                         /* TODO: thick grain mail operation involving
169                            a list of objects. Composite pattern ??? */
170                         /* TODO: add confirmation dialog */
171                         mail_op = modest_mail_operation_new ();
172                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
173                                                          mail_op);
174
175                         /* Always delete. TODO: Move to trash still not supported */
176                         modest_mail_operation_remove_msg (mail_op, header, FALSE);
177
178                         /* Frees */
179                         g_object_unref (G_OBJECT (mail_op));
180                         g_object_unref (G_OBJECT (header));
181
182                         tny_iterator_next (iter);
183
184                 } while (!tny_iterator_is_done (iter));
185
186                 /* Free iter */
187                 g_object_unref (G_OBJECT (iter));
188         }
189
190         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
191                 gtk_widget_destroy (GTK_WIDGET(win));
192         } 
193 }
194
195
196 void
197 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
198 {
199         gtk_main_quit ();
200 }
201
202 void
203 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
204 {
205         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
206                 gtk_widget_destroy (GTK_WIDGET (win));
207         } else if (MODEST_IS_WINDOW (win)) {
208                 gtk_widget_destroy (GTK_WIDGET (win));
209         } else {
210                 g_return_if_reached ();
211         }
212 }
213
214 void
215 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
216 {
217         GtkClipboard *clipboard = NULL;
218         gchar *selection = NULL;
219
220         clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
221         selection = gtk_clipboard_wait_for_text (clipboard);
222
223         modest_address_book_add_address (selection);
224         g_free (selection);
225 }
226
227 void
228 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
229 {
230         
231         /* This is currently only implemented for Maemo,
232          * because it requires a providers preset file which is not publically available.
233          */
234 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
235         GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr());
236         gboolean accounts_exist = account_names != NULL;
237         g_slist_free (account_names);
238         
239 /* To test, while modest_account_mgr_account_names() is broken: accounts_exist = TRUE; */
240         if (!accounts_exist) {
241                 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
242                 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
243                 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
244                 gtk_dialog_run (GTK_DIALOG (wizard));
245                 gtk_widget_destroy (GTK_WIDGET (wizard));
246         } else  {
247                 /* Show the list of accounts: */
248                 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
249                 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
250                 gtk_dialog_run (account_win);
251                 gtk_widget_destroy (GTK_WIDGET(account_win));
252         }
253 #else
254         GtkWidget *dialog, *label;
255         
256         /* Create the widgets */
257         
258         dialog = gtk_dialog_new_with_buttons ("Message",
259                                               GTK_WINDOW(win),
260                                               GTK_DIALOG_DESTROY_WITH_PARENT,
261                                               GTK_STOCK_OK,
262                                               GTK_RESPONSE_NONE,
263                                               NULL);
264         label = gtk_label_new ("Hello World!");
265         
266         /* Ensure that the dialog box is destroyed when the user responds. */
267         
268         g_signal_connect_swapped (dialog, "response", 
269                                   G_CALLBACK (gtk_widget_destroy),
270                                   dialog);
271         
272         /* Add the label, and show everything we've added to the dialog. */
273         
274         gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
275                            label);
276         gtk_widget_show_all (dialog);
277 #endif /* MODEST_PLATFORM_MAEMO */
278 }
279
280 void
281 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
282 {
283         ModestWindow *msg_win;
284         TnyMsg *msg = NULL;
285         TnyFolder *folder = NULL;
286         gchar *account_name = NULL;
287         gchar *from_str = NULL;
288         GError *err = NULL;
289         TnyAccount *account = NULL;
290         ModestWindowMgr *mgr;
291         
292         account_name = g_strdup(modest_window_get_active_account (win));
293         if (!account_name)
294                 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
295         if (!account_name) {
296                 g_printerr ("modest: no account found\n");
297                 goto cleanup;
298         }
299         
300         account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
301                                                                        account_name,
302                                                                        TNY_ACCOUNT_TYPE_STORE);
303         if (!account) {
304                 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
305                 goto cleanup;
306         }
307
308         from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
309         if (!from_str) {
310                 g_printerr ("modest: failed get from string for '%s'\n", account_name);
311                 goto cleanup;
312         }
313
314         msg = modest_tny_msg_new ("", from_str, "", "", "", "", NULL);
315         if (!msg) {
316                 g_printerr ("modest: failed to create new msg\n");
317                 goto cleanup;
318         }
319         
320         folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
321         if (!folder) {
322                 g_printerr ("modest: failed to find Drafts folder\n");
323                 goto cleanup;
324         }
325         
326         tny_folder_add_msg (folder, msg, &err);
327         if (err) {
328                 g_printerr ("modest: error adding msg to Drafts folder: %s",
329                             err->message);
330                 g_error_free (err);
331                 goto cleanup;
332         }
333
334         /* Create and register edit window */
335         msg_win = modest_msg_edit_window_new (msg, account_name);
336         mgr = modest_runtime_get_window_mgr ();
337         modest_window_mgr_register_window (mgr, msg_win);
338
339         if (win)
340                 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
341                                               GTK_WINDOW (win));        
342         gtk_widget_show_all (GTK_WIDGET (msg_win));
343
344 cleanup:
345         g_free (account_name);
346         g_free (from_str);
347         if (account)
348                 g_object_unref (G_OBJECT(account));
349         if (msg)
350                 g_object_unref (G_OBJECT(msg));
351         if (folder)
352                 g_object_unref (G_OBJECT(folder));
353 }
354
355
356 void
357 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
358 {
359         modest_runtime_not_implemented (GTK_WINDOW(win)); /* FIXME */
360 }
361
362
363
364 static void
365 reply_forward_func (gpointer data, gpointer user_data)
366 {
367         TnyMsg *msg, *new_msg;
368         GetMsgAsyncHelper *helper;
369         ReplyForwardHelper *rf_helper;
370         ModestWindow *msg_win;
371         ModestEditType edit_type;
372         gchar *from;
373         GError *err = NULL;
374         TnyFolder *folder = NULL;
375         TnyAccount *account = NULL;
376         ModestWindowMgr *mgr;
377         
378         msg = TNY_MSG (data);
379         helper = (GetMsgAsyncHelper *) user_data;
380         rf_helper = (ReplyForwardHelper *) helper->user_data;
381
382         from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
383                                                    rf_helper->account_name);
384         /* Create reply mail */
385         switch (rf_helper->action) {
386         case ACTION_REPLY:
387                 new_msg = 
388                         modest_tny_msg_create_reply_msg (msg,  from, 
389                                                          rf_helper->reply_forward_type,
390                                                          MODEST_TNY_MSG_REPLY_MODE_SENDER);
391                 break;
392         case ACTION_REPLY_TO_ALL:
393                 new_msg = 
394                         modest_tny_msg_create_reply_msg (msg, from, rf_helper->reply_forward_type,
395                                                          MODEST_TNY_MSG_REPLY_MODE_ALL);
396                 edit_type = MODEST_EDIT_TYPE_REPLY;
397                 break;
398         case ACTION_FORWARD:
399                 new_msg = 
400                         modest_tny_msg_create_forward_msg (msg, from, rf_helper->reply_forward_type);
401                 edit_type = MODEST_EDIT_TYPE_FORWARD;
402                 break;
403         default:
404                 g_return_if_reached ();
405                 return;
406         }
407
408         if (!new_msg) {
409                 g_printerr ("modest: failed to create message\n");
410                 goto cleanup;
411         }
412
413         account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
414                                                                        rf_helper->account_name,
415                                                                        TNY_ACCOUNT_TYPE_STORE);
416         if (!account) {
417                 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
418                 goto cleanup;
419         }
420
421         folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
422         if (!folder) {
423                 g_printerr ("modest: failed to find Drafts folder\n");
424                 goto cleanup;
425         }
426         
427         tny_folder_add_msg (folder, msg, &err);
428         if (err) {
429                 g_printerr ("modest: error adding msg to Drafts folder: %s",
430                             err->message);
431                 g_error_free (err);
432                 goto cleanup;
433         }       
434
435         /* Create and register the windows */                   
436         msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
437         mgr = modest_runtime_get_window_mgr ();
438         modest_window_mgr_register_window (mgr, msg_win);
439
440         /* Show edit window */
441         gtk_widget_show_all (GTK_WIDGET (msg_win));
442
443 cleanup:
444         if (new_msg)
445                 g_object_unref (G_OBJECT (new_msg));
446         if (folder)
447                 g_object_unref (G_OBJECT (folder));
448         if (account)
449                 g_object_unref (G_OBJECT (account));
450         
451         g_free (rf_helper->account_name);
452         g_slice_free (ReplyForwardHelper, rf_helper);
453 }
454 /*
455  * Common code for the reply and forward actions
456  */
457 static void
458 reply_forward (ReplyForwardAction action, ModestWindow *win)
459 {
460         TnyList *header_list;
461         guint reply_forward_type;
462         TnyHeader *header;
463         TnyFolder *folder;
464         GetMsgAsyncHelper *helper;
465         ReplyForwardHelper *rf_helper;
466         
467         g_return_if_fail (MODEST_IS_WINDOW(win));
468
469         header_list = get_selected_headers (win);
470         if (!header_list)
471                 return;
472         
473         reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (),
474                                                   (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
475                                                   NULL);
476         /* We assume that we can only select messages of the
477            same folder and that we reply all of them from the
478            same account. In fact the interface currently only
479            allows single selection */
480         
481         /* Fill helpers */
482         rf_helper = g_slice_new0 (ReplyForwardHelper);
483         rf_helper->reply_forward_type = reply_forward_type;
484         rf_helper->action = action;
485
486         rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
487         if (!rf_helper->account_name)
488                 rf_helper->account_name =
489                         modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
490
491         helper = g_slice_new0 (GetMsgAsyncHelper);
492         helper->window = win;
493         helper->func = reply_forward_func;
494         helper->iter = tny_list_create_iterator (header_list);
495         helper->user_data = rf_helper;
496
497         if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
498                 TnyMsg *msg;
499                 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
500                 if (!msg) {
501                         g_printerr ("modest: no message found\n");
502                         return;
503                 } else
504                         reply_forward_func (msg, helper);
505         } else {
506                 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
507                 folder = tny_header_get_folder (header);
508                 if (folder) {
509                         /* The callback will call it per each header */
510                         tny_folder_get_msg_async (folder, header, get_msg_cb, NULL, helper);
511                         g_object_unref (G_OBJECT (folder));
512                 } else 
513                         g_printerr ("modest: no folder for header\n");
514                 
515                 /* Clean */
516                 g_object_unref (G_OBJECT (header));
517         }
518 }
519
520
521 void
522 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
523 {
524         g_return_if_fail (MODEST_IS_WINDOW(win));
525
526         reply_forward (ACTION_REPLY, win);
527 }
528
529 void
530 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
531 {
532         g_return_if_fail (MODEST_IS_WINDOW(win));
533
534         reply_forward (ACTION_FORWARD, win);
535 }
536
537 void
538 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
539 {
540         g_return_if_fail (MODEST_IS_WINDOW(win));
541
542         reply_forward (ACTION_REPLY_TO_ALL, win);
543 }
544
545 void 
546 modest_ui_actions_on_next (GtkAction *action, 
547                            ModestWindow *window)
548 {
549         if (MODEST_IS_MAIN_WINDOW (window)) {
550                 GtkWidget *header_view;
551
552                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
553                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
554                 if (!header_view)
555                         return;
556         
557                 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view)); 
558         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
559                 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
560         } else {
561                 g_return_if_reached ();
562         }
563 }
564
565 void 
566 modest_ui_actions_on_prev (GtkAction *action, 
567                            ModestWindow *window)
568 {
569         g_return_if_fail (MODEST_IS_WINDOW(window));
570
571         if (MODEST_IS_MAIN_WINDOW (window)) {
572                 GtkWidget *header_view;
573                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
574                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
575                 if (!header_view)
576                         return;
577                 
578                 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view)); 
579         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
580                 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
581         } else {
582                 g_return_if_reached ();
583         }
584 }
585
586 void 
587 modest_ui_actions_on_sort (GtkAction *action, 
588                            ModestWindow *window)
589 {
590         ModestWindowMgr *mgr;
591
592         g_return_if_fail (MODEST_IS_WINDOW(window));
593
594         /* Show sorting dialog */
595         mgr = modest_runtime_get_window_mgr ();
596         
597 }
598
599
600 static gboolean
601 action_send (const gchar* account_name)
602 {
603         TnyAccount *tny_account;
604         ModestTnySendQueue *send_queue;
605
606         g_return_val_if_fail (account_name, FALSE);
607
608         /* Get the transport account according to the open connection, 
609          * because the account might specify connection-specific SMTP servers.
610          */
611         tny_account = 
612                 modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(),
613                                                                      account_name);
614         if (!tny_account) {
615                 g_printerr ("modest: cannot get tny transport account for %s\n", account_name);
616                 return FALSE;
617         }
618         
619         send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(tny_account));
620         if (!send_queue) {
621                 g_object_unref (G_OBJECT(tny_account));
622                 g_printerr ("modest: cannot get send queue for %s\n", account_name);
623                 return FALSE;
624         }
625         
626         //modest_tny_send_queue_flush (send_queue);
627
628         g_object_unref (G_OBJECT(send_queue));
629         g_object_unref (G_OBJECT(tny_account));
630
631         return TRUE;
632 }
633
634
635 static gboolean
636 action_receive (const gchar* account_name)
637 {
638         TnyAccount *tny_account;
639         ModestMailOperation *mail_op;
640
641         g_return_val_if_fail (account_name, FALSE);
642
643         tny_account = 
644                 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
645                                                                      account_name,
646                                                                      TNY_ACCOUNT_TYPE_STORE);
647         if (!tny_account) {
648                 g_printerr ("modest: cannot get tny store account for %s\n", account_name);
649                 return FALSE;
650         }
651
652         /* Create the mail operation */
653         /* TODO: The spec wants us to first do any pending deletions, before receiving. */
654         mail_op = modest_mail_operation_new ();
655         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
656         modest_mail_operation_update_account (mail_op, TNY_STORE_ACCOUNT(tny_account));
657
658         g_object_unref (G_OBJECT(tny_account));
659         g_object_unref (G_OBJECT (mail_op));
660                 
661         return TRUE;
662 }
663
664 /** Check that an appropriate connection is open.
665  */
666 gboolean check_for_connection (const gchar *account_name)
667 {
668         TnyDevice *device = modest_runtime_get_device ();
669
670 /*
671         g_assert (TNY_IS_MAEMO_CONIC_DEVICE (device));
672         
673         TnyMaemoConicDevice *maemo_device = TNY_MAEMO_CONIC_DEVICE (device);
674 */
675         
676         if (tny_device_is_online (device))
677                 return TRUE;
678         else {
679                 modest_platform_connect_and_wait (NULL);
680                 
681                 /* TODO: Wait until a result. */
682                 return TRUE;
683         }
684 }
685
686 void
687 modest_ui_actions_on_send_receive (GtkAction *action,  ModestWindow *win)
688 {
689         gchar *account_name;
690
691         
692         g_message ("%s: online? %s", __FUNCTION__,  
693                 tny_device_is_online(modest_runtime_get_device()) ? "yes":"no");
694                                 
695         /* As per the UI spec, only the active account should be affected, 
696          * else the default folder if there is no active account: */                            
697         account_name =
698                 g_strdup(modest_window_get_active_account(MODEST_WINDOW(win)));
699         if (!account_name)
700                 account_name  = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
701         if (!account_name) {
702                 g_printerr ("modest: cannot get default account\n");
703                 return;
704         }
705         
706         /* Do not continue if no suitable connection is open: */
707         if (!check_for_connection (account_name))
708                 return;
709
710         /* As per the UI spec,
711          * for POP accounts, we should receive,
712          * for IMAP we should synchronize everything, including receiving,
713          * for SMTP we should send,
714          * first receiving, then sending:
715          */
716         if (!action_receive(account_name))
717                 g_printerr ("modest: failed to receive\n");
718         if (!action_send(account_name))
719                 g_printerr ("modest: failed to send\n");
720         
721 }
722
723
724
725 void
726 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
727 {
728         ModestConf *conf;
729         GtkWidget *header_view;
730         
731         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
732
733         header_view = modest_main_window_get_child_widget (main_window,
734                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
735         if (!header_view)
736                 return;
737
738         conf = modest_runtime_get_conf ();
739         
740         /* what is saved/restored is depending on the style; thus; we save with
741          * old style, then update the style, and restore for this new style
742          */
743         modest_widget_memory_save (conf, G_OBJECT(header_view), "header-view");
744         
745         if (modest_header_view_get_style
746             (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
747                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
748                                               MODEST_HEADER_VIEW_STYLE_TWOLINES);
749         else
750                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
751                                               MODEST_HEADER_VIEW_STYLE_DETAILS);
752
753         modest_widget_memory_restore (conf, G_OBJECT(header_view),
754                                       "header-view");
755 }
756
757
758
759 /*
760  * Marks a message as read and passes it to the msg preview widget
761  */
762 static void
763 read_msg_func (gpointer data, gpointer user_data)
764 {
765         TnyMsg *msg;
766         TnyHeader *header;
767         GetMsgAsyncHelper *helper;
768         TnyHeaderFlags header_flags;
769         GtkWidget *msg_preview;
770         
771         msg = TNY_MSG (data);
772         helper = (GetMsgAsyncHelper *) user_data;
773
774         msg_preview = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (helper->window),
775                                                            MODEST_WIDGET_TYPE_MSG_PREVIEW);
776         if (!msg_preview)
777                 return;
778         
779         header = TNY_HEADER (tny_iterator_get_current (helper->iter));
780         header_flags = tny_header_get_flags (header);
781         tny_header_set_flags (header, header_flags | TNY_HEADER_FLAG_SEEN);
782         g_object_unref (G_OBJECT (header));
783
784         /* Set message on msg view */
785         modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), msg);
786 }
787
788 /*
789  * This function is a generic handler for the tny_folder_get_msg_async
790  * call. It expects as user_data a #GetMsgAsyncHelper. This helper
791  * contains a user provided function that is called inside this
792  * method. This will allow us to use this callback in many different
793  * places. This callback performs the common actions for the
794  * get_msg_async call, more specific actions will be done by the user
795  * function
796  */
797 static void
798 get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data)
799 {
800         GetMsgAsyncHelper *helper;
801
802         helper = (GetMsgAsyncHelper *) user_data;
803
804         if ((*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) || !msg) {
805                 modest_ui_actions_on_item_not_found (NULL,
806                                                      MODEST_ITEM_TYPE_MESSAGE,
807                                                      helper->window);
808                 return;
809         }
810
811         /* Call user function */
812         helper->func (msg, user_data);
813
814         /* Process next element (if exists) */
815         tny_iterator_next (helper->iter);
816         if (tny_iterator_is_done (helper->iter)) {
817                 TnyList *headers;
818                 headers = tny_iterator_get_list (helper->iter);
819                 /* Free resources */
820                 g_object_unref (G_OBJECT (headers));
821                 g_object_unref (G_OBJECT (helper->iter));
822                 g_slice_free (GetMsgAsyncHelper, helper);
823         } else {
824                 TnyHeader *header;
825                 header = TNY_HEADER (tny_iterator_get_current (helper->iter)); 
826                 tny_folder_get_msg_async (folder, header,                         
827                                           get_msg_cb, NULL, helper);
828                 g_object_unref (G_OBJECT(header));
829         }
830 }
831
832 void 
833 modest_ui_actions_on_header_selected (ModestHeaderView *header_view, 
834                                       TnyHeader *header,
835                                       ModestMainWindow *main_window)
836 {
837         TnyFolder *folder;
838         GetMsgAsyncHelper *helper;
839         TnyList *list;
840
841         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
842
843         /* when there's no header, clear the msgview */
844         if (!header) {
845                 GtkWidget *msg_preview;
846
847                 /* Clear msg preview if exists */
848                 msg_preview = modest_main_window_get_child_widget(main_window,
849                                                                   MODEST_WIDGET_TYPE_MSG_PREVIEW);
850         
851                 if (msg_preview)
852                         modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), NULL);
853                 return;
854         }
855
856         /* Update Main window title */
857         if (GTK_WIDGET_HAS_FOCUS (header_view)) {
858                 const gchar *subject = tny_header_get_subject (header);
859                 if (subject && strcmp (subject, ""))
860                         gtk_window_set_title (GTK_WINDOW (main_window), subject);
861                 else
862                         gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
863         }
864
865         /* Create list */
866         list = tny_simple_list_new ();
867         tny_list_prepend (list, G_OBJECT (header));
868
869         /* Fill helper data */
870         helper = g_slice_new0 (GetMsgAsyncHelper);
871         helper->window = MODEST_WINDOW (main_window);
872         helper->iter = tny_list_create_iterator (list);
873         helper->func = read_msg_func;
874
875         folder = tny_header_get_folder (TNY_HEADER(header));
876
877         tny_folder_get_msg_async (TNY_FOLDER(folder),
878                                   header, get_msg_cb,
879                                   NULL, helper);
880
881         /* Frees */
882         g_object_unref (G_OBJECT (folder));
883 }
884
885
886
887 void 
888 modest_ui_actions_on_header_activated (ModestHeaderView *folder_view, TnyHeader *header,
889                                        ModestMainWindow *main_window)
890 {
891         ModestWindow *win = NULL;
892         TnyFolder *folder = NULL;
893         TnyMsg    *msg    = NULL;
894         ModestWindowMgr *mgr;
895         
896         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
897         
898         if (!header)
899                 return;
900
901         folder = tny_header_get_folder (header);
902         if (!folder) {
903                 g_printerr ("modest: cannot get folder for header\n");
904                 return;
905         }
906
907         /* FIXME: make async?; check error  */
908         msg = tny_folder_get_msg (folder, header, NULL);
909         if (!msg) {
910                 g_printerr ("modest: cannot get msg for header\n");
911                 goto cleanup;
912         }
913
914         /* Look if we already have a message view for that header */    
915         mgr = modest_runtime_get_window_mgr ();
916         win = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
917
918         /* If not, create a new window */
919         if (!win) {
920                 gchar *account;
921
922                 account =  g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window)));
923                 if (!account)
924                         account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
925
926                 win = modest_msg_view_window_new (msg, account);
927                 modest_window_mgr_register_window (mgr, win);
928
929                 gtk_window_set_transient_for (GTK_WINDOW (win),
930                                               GTK_WINDOW (main_window));
931         }
932
933         gtk_widget_show_all (GTK_WIDGET(win));
934
935         g_object_unref (G_OBJECT (msg));
936         
937 cleanup:
938         g_object_unref (G_OBJECT (folder));
939 }
940
941 void 
942 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
943                                                TnyFolderStore *folder_store, 
944                                                gboolean selected,
945                                                ModestMainWindow *main_window)
946 {
947         ModestConf *conf;
948         GtkWidget *header_view;
949         
950         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
951
952         header_view = modest_main_window_get_child_widget(main_window,
953                                                           MODEST_WIDGET_TYPE_HEADER_VIEW);
954         if (!header_view)
955                 return;
956         
957         conf = modest_runtime_get_conf ();
958
959         if (TNY_IS_FOLDER (folder_store)) {
960
961                 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
962
963                 if (selected) {
964                         modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
965                                                        TNY_FOLDER (folder_store));
966                         modest_widget_memory_restore (conf, G_OBJECT(header_view),
967                                                       "header-view");
968                 } else {
969                         modest_widget_memory_save (conf, G_OBJECT (header_view), "header-view");
970                         modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
971                 }
972         } else if (TNY_IS_ACCOUNT (folder_store)) {
973
974                 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
975         }
976 }
977
978 void 
979 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
980                                      ModestWindow *win)
981 {
982         GtkWidget *dialog;
983         gchar *txt, *item;
984         gboolean online;
985
986         item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
987         
988         if (g_main_depth > 0)   
989                 gdk_threads_enter ();
990         online = tny_device_is_online (modest_runtime_get_device());
991
992         if (online) {
993                 /* already online -- the item is simply not there... */
994                 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
995                                                  GTK_DIALOG_MODAL,
996                                                  GTK_MESSAGE_WARNING,
997                                                  GTK_BUTTONS_OK,
998                                                  _("The %s you selected cannot be found"),
999                                                  item);
1000                 gtk_dialog_run (GTK_DIALOG(dialog));
1001         } else {
1002                 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1003                                                       GTK_WINDOW (win),
1004                                                       GTK_DIALOG_MODAL,
1005                                                       GTK_STOCK_CANCEL,
1006                                                       GTK_RESPONSE_REJECT,
1007                                                       GTK_STOCK_OK,
1008                                                       GTK_RESPONSE_ACCEPT,
1009                                                       NULL);
1010                 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1011                                          "Do you want to get online?"), item);
1012                 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1013                                     gtk_label_new (txt), FALSE, FALSE, 0);
1014                 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1015                 g_free (txt);
1016
1017                 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1018                 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1019 //                      modest_platform_connect_and_wait ();;
1020                 }
1021         }
1022         gtk_widget_destroy (dialog);
1023         if (g_main_depth > 0)   
1024                 gdk_threads_leave ();
1025 }
1026
1027 void
1028 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1029                                      ModestWindow *win)
1030 {
1031         g_message ("%s %s", __FUNCTION__, link);
1032 }       
1033
1034
1035 void
1036 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1037                                         ModestWindow *win)
1038 {
1039         modest_platform_activate_uri (link);
1040 }
1041
1042 void
1043 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1044                                           ModestWindow *win)
1045 {
1046         modest_platform_show_uri_popup (link);
1047 }
1048
1049 void
1050 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1051                                              ModestWindow *win)
1052 {
1053         g_message (__FUNCTION__);
1054         
1055 }
1056
1057 void
1058 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1059                                           const gchar *address,
1060                                           ModestWindow *win)
1061 {
1062         g_message ("%s %s", __FUNCTION__, address);
1063 }
1064
1065 void
1066 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1067 {
1068         TnyTransportAccount *transport_account;
1069         ModestMailOperation *mail_operation;
1070         MsgData *data;
1071         gchar *account_name, *from;
1072         ModestAccountMgr *account_mgr;
1073
1074         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1075         
1076         data = modest_msg_edit_window_get_msg_data (edit_window);
1077
1078         /* FIXME: Code added just for testing. The final version will
1079            use the send queue provided by tinymail and some
1080            classifier */
1081         account_mgr = modest_runtime_get_account_mgr();
1082         account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1083         if (!account_name) 
1084                 account_name = modest_account_mgr_get_default_account (account_mgr);
1085         if (!account_name) {
1086                 g_printerr ("modest: no account found\n");
1087                 modest_msg_edit_window_free_msg_data (edit_window, data);
1088                 return;
1089         }
1090         transport_account =
1091                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1092                                       (modest_runtime_get_account_store(),
1093                                        account_name));
1094         if (!transport_account) {
1095                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1096                 g_free (account_name);
1097                 modest_msg_edit_window_free_msg_data (edit_window, data);
1098                 return;
1099         }
1100         from = modest_account_mgr_get_from_string (account_mgr, account_name);
1101
1102         /* Create the mail operation */         
1103         mail_operation = modest_mail_operation_new ();
1104         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1105
1106         modest_mail_operation_send_new_mail (mail_operation,
1107                                              transport_account,
1108                                              from,
1109                                              data->to, 
1110                                              data->cc, 
1111                                              data->bcc,
1112                                              data->subject, 
1113                                              data->plain_body, 
1114                                              data->html_body,
1115                                              data->attachments,
1116                                              data->priority_flags);
1117         /* Frees */
1118         g_free (from);
1119         g_free (account_name);
1120         g_object_unref (G_OBJECT (transport_account));
1121         g_object_unref (G_OBJECT (mail_operation));
1122
1123         modest_msg_edit_window_free_msg_data (edit_window, data);
1124
1125         /* Save settings and close the window */
1126         gtk_widget_destroy (GTK_WIDGET (edit_window));
1127 }
1128
1129 void 
1130 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1131                                   ModestMsgEditWindow *window)
1132 {
1133         ModestMsgEditFormatState *format_state = NULL;
1134
1135         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1136         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1137
1138         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1139                 return;
1140
1141         format_state = modest_msg_edit_window_get_format_state (window);
1142         g_return_if_fail (format_state != NULL);
1143
1144         format_state->bold = gtk_toggle_action_get_active (action);
1145         modest_msg_edit_window_set_format_state (window, format_state);
1146         g_free (format_state);
1147         
1148 }
1149
1150 void 
1151 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1152                                      ModestMsgEditWindow *window)
1153 {
1154         ModestMsgEditFormatState *format_state = NULL;
1155
1156         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1157         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1158
1159         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1160                 return;
1161
1162         format_state = modest_msg_edit_window_get_format_state (window);
1163         g_return_if_fail (format_state != NULL);
1164
1165         format_state->italics = gtk_toggle_action_get_active (action);
1166         modest_msg_edit_window_set_format_state (window, format_state);
1167         g_free (format_state);
1168         
1169 }
1170
1171 void 
1172 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1173                                      ModestMsgEditWindow *window)
1174 {
1175         ModestMsgEditFormatState *format_state = NULL;
1176
1177         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1178         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1179
1180         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1181                 return;
1182
1183         format_state = modest_msg_edit_window_get_format_state (window);
1184         g_return_if_fail (format_state != NULL);
1185
1186         format_state->bullet = gtk_toggle_action_get_active (action);
1187         modest_msg_edit_window_set_format_state (window, format_state);
1188         g_free (format_state);
1189         
1190 }
1191
1192 void 
1193 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1194                                      GtkRadioAction *selected,
1195                                      ModestMsgEditWindow *window)
1196 {
1197         ModestMsgEditFormatState *format_state = NULL;
1198         GtkJustification value;
1199
1200         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1201
1202         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1203                 return;
1204
1205         value = gtk_radio_action_get_current_value (selected);
1206
1207         format_state = modest_msg_edit_window_get_format_state (window);
1208         g_return_if_fail (format_state != NULL);
1209
1210         format_state->justification = value;
1211         modest_msg_edit_window_set_format_state (window, format_state);
1212         g_free (format_state);
1213 }
1214
1215 void 
1216 modest_ui_actions_on_select_editor_color (GtkAction *action,
1217                                           ModestMsgEditWindow *window)
1218 {
1219         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1220         g_return_if_fail (GTK_IS_ACTION (action));
1221
1222         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1223                 return;
1224
1225         modest_msg_edit_window_select_color (window);
1226 }
1227
1228 void 
1229 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1230                                                      ModestMsgEditWindow *window)
1231 {
1232         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1233         g_return_if_fail (GTK_IS_ACTION (action));
1234
1235         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1236                 return;
1237
1238         modest_msg_edit_window_select_background_color (window);
1239 }
1240
1241 void 
1242 modest_ui_actions_on_insert_image (GtkAction *action,
1243                                    ModestMsgEditWindow *window)
1244 {
1245         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1246         g_return_if_fail (GTK_IS_ACTION (action));
1247
1248         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1249                 return;
1250
1251         modest_msg_edit_window_insert_image (window);
1252 }
1253
1254 /*
1255  * Shows a dialog with an entry that asks for some text. The returned
1256  * value must be freed by the caller. The dialog window title will be
1257  * set to @title.
1258  */
1259 static gchar *
1260 ask_for_folder_name (GtkWindow *parent_window,
1261                      const gchar *title)
1262 {
1263         GtkWidget *dialog, *entry;
1264         gchar *folder_name = NULL;
1265
1266         /* Ask for folder name */
1267         dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1268                                               parent_window,
1269                                               GTK_DIALOG_MODAL,
1270                                               GTK_STOCK_CANCEL,
1271                                               GTK_RESPONSE_REJECT,
1272                                               GTK_STOCK_OK,
1273                                               GTK_RESPONSE_ACCEPT,
1274                                               NULL);
1275         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1276                             gtk_label_new(title),
1277                             FALSE, FALSE, 0);
1278                 
1279         entry = gtk_entry_new_with_max_length (40);
1280         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1281                             entry,
1282                             TRUE, FALSE, 0);    
1283         
1284         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1285         
1286         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)         
1287                 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1288
1289         gtk_widget_destroy (dialog);
1290
1291         return folder_name;
1292 }
1293
1294 void 
1295 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1296 {
1297         TnyFolderStore *parent_folder;
1298         GtkWidget *folder_view;
1299         
1300         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1301
1302         folder_view = modest_main_window_get_child_widget (main_window,
1303                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1304         if (!folder_view)
1305                 return;
1306
1307         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1308         
1309         if (parent_folder) {
1310                 gboolean finished = FALSE;
1311                 gint result;
1312                 gchar *folder_name = NULL, *suggested_name = NULL;
1313
1314                 /* Run the new folder dialog */
1315                 while (!finished) {
1316                         result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1317                                                                         parent_folder,
1318                                                                         suggested_name,
1319                                                                         &folder_name);
1320
1321                         if (result == GTK_RESPONSE_REJECT) {
1322                                 finished = TRUE;
1323                         } else {
1324                                 ModestMailOperation *mail_op = modest_mail_operation_new ();
1325                                 TnyFolder *new_folder = NULL;
1326
1327                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
1328                                                                  mail_op);
1329                 
1330                                 new_folder = modest_mail_operation_create_folder (mail_op,
1331                                                                                   parent_folder,
1332                                                                                   (const gchar *) folder_name);
1333                                 if (new_folder) {
1334                                         g_object_unref (new_folder);
1335                                         finished = TRUE;
1336                                 } 
1337 /*                              else { */
1338 /*                                      /\* TODO: check error and follow proper actions *\/ */
1339 /* /\*                                  suggested_name = X; *\/ */
1340 /*                                      /\* Show error to the user *\/ */
1341 /*                                      modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
1342 /*                                                                              MODEST_INFORMATION_CREATE_FOLDER); */
1343 /*                              } */
1344                                 g_object_unref (mail_op);
1345                         }
1346                         g_free (folder_name);
1347                         folder_name = NULL;
1348                 }
1349
1350                 g_object_unref (parent_folder);
1351         }
1352 }
1353
1354 void 
1355 modest_ui_actions_on_rename_folder (GtkAction *action,
1356                                      ModestMainWindow *main_window)
1357 {
1358         TnyFolderStore *folder;
1359         GtkWidget *folder_view;
1360         
1361         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1362
1363         folder_view = modest_main_window_get_child_widget (main_window,
1364                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1365         if (!folder_view)
1366                 return;
1367         
1368         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1369         
1370         if (folder && TNY_IS_FOLDER (folder)) {
1371                 gchar *folder_name;
1372                 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1373                                                    _("Please enter a new name for the folder"));
1374
1375                 if (folder_name != NULL && strlen (folder_name) > 0) {
1376                         ModestMailOperation *mail_op;
1377
1378                         mail_op = modest_mail_operation_new ();
1379                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1380                                                          mail_op);
1381
1382                         modest_mail_operation_rename_folder (mail_op,
1383                                                              TNY_FOLDER (folder),
1384                                                              (const gchar *) folder_name);
1385
1386                         g_object_unref (mail_op);
1387                         g_free (folder_name);
1388                 }
1389                 g_object_unref (folder);
1390         }
1391 }
1392
1393 static void
1394 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash) 
1395 {
1396         TnyFolderStore *folder;
1397         GtkWidget *folder_view;
1398         gint response;
1399         gchar *message;
1400         
1401         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1402
1403         folder_view = modest_main_window_get_child_widget (main_window,
1404                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1405         if (!folder_view)
1406                 return;
1407
1408         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1409
1410         /* Ask the user */      
1411         message =  g_strdup_printf (_("mcen_nc_delete_folder_text"), 
1412                                     tny_folder_get_name (TNY_FOLDER (folder)));
1413         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window), 
1414                                                             (const gchar *) message);
1415         g_free (message);
1416
1417         if (response == GTK_RESPONSE_OK) {
1418                 ModestMailOperation *mail_op = modest_mail_operation_new ();
1419
1420                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1421                                                  mail_op);
1422                 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1423
1424                 /* Show error if happened */
1425                 if (modest_mail_operation_get_error (mail_op))
1426                         modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1427                                                                 MODEST_INFORMATION_DELETE_FOLDER);
1428
1429                 g_object_unref (G_OBJECT (mail_op));
1430         }
1431
1432         g_object_unref (G_OBJECT (folder));
1433 }
1434
1435 void 
1436 modest_ui_actions_on_delete_folder (GtkAction *action,
1437                                      ModestMainWindow *main_window)
1438 {
1439         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1440
1441         delete_folder (main_window, FALSE);
1442 }
1443
1444 void 
1445 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1446 {
1447         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1448         
1449         delete_folder (main_window, TRUE);
1450 }
1451
1452 void
1453 modest_ui_actions_on_password_requested (TnyAccountStore *account_store, 
1454                                          const gchar* account_name,
1455                                          gchar **password, 
1456                                          gboolean *cancel, 
1457                                          gboolean *remember,
1458                                          ModestMainWindow *main_window)
1459 {
1460         gchar *txt;
1461         GtkWidget *dialog, *entry, *remember_pass_check;
1462
1463         dialog = gtk_dialog_new_with_buttons (_("Password requested"),
1464                                               NULL,
1465                                               GTK_DIALOG_MODAL,
1466                                               GTK_STOCK_CANCEL,
1467                                               GTK_RESPONSE_REJECT,
1468                                               GTK_STOCK_OK,
1469                                               GTK_RESPONSE_ACCEPT,
1470                                               NULL);
1471         gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1472         
1473         txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
1474         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1475                             FALSE, FALSE, 0);
1476         g_free (txt);
1477
1478         entry = gtk_entry_new_with_max_length (40);
1479         gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
1480         gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
1481         
1482         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
1483                             TRUE, FALSE, 0);    
1484
1485         remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1486         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1487                             TRUE, FALSE, 0);
1488
1489         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1490         
1491         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1492                 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
1493                 *cancel   = FALSE;
1494         } else {
1495                 *password = NULL;
1496                 *cancel   = TRUE;
1497         }
1498
1499         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1500                 *remember = TRUE;
1501         else
1502                 *remember = FALSE;
1503
1504         gtk_widget_destroy (dialog);
1505 }
1506
1507 void
1508 modest_ui_actions_on_cut (GtkAction *action,
1509                           ModestWindow *window)
1510 {
1511         GtkWidget *focused_widget;
1512
1513         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1514         if (GTK_IS_EDITABLE (focused_widget)) {
1515                 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1516         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1517                 GtkTextBuffer *buffer;
1518                 GtkClipboard *clipboard;
1519
1520                 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1521                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1522                 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1523         }
1524 }
1525
1526 void
1527 modest_ui_actions_on_copy (GtkAction *action,
1528                            ModestWindow *window)
1529 {
1530         GtkClipboard *clipboard;
1531         GtkWidget *focused_widget;
1532
1533         clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1534         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1535         if (GTK_IS_LABEL (focused_widget)) {
1536                 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1537         } else if (GTK_IS_EDITABLE (focused_widget)) {
1538                 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1539         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1540                 GtkTextBuffer *buffer;
1541
1542                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1543                 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1544         }
1545 }
1546
1547 void
1548 modest_ui_actions_on_undo (GtkAction *action,
1549                            ModestWindow *window)
1550 {
1551         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
1552                 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
1553         } else {
1554                 g_return_if_reached ();
1555         }
1556 }
1557
1558 void
1559 modest_ui_actions_on_paste (GtkAction *action,
1560                             ModestWindow *window)
1561 {
1562         GtkWidget *focused_widget;
1563
1564         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1565         if (GTK_IS_EDITABLE (focused_widget)) {
1566                 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1567         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1568                 GtkTextBuffer *buffer;
1569                 GtkClipboard *clipboard;
1570
1571                 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1572                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1573                 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1574         }
1575 }
1576
1577 void
1578 modest_ui_actions_on_select_all (GtkAction *action,
1579                                  ModestWindow *window)
1580 {
1581         GtkWidget *focused_widget;
1582
1583         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1584         if (GTK_IS_LABEL (focused_widget)) {
1585                 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1586         } else if (GTK_IS_EDITABLE (focused_widget)) {
1587                 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1588         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1589                 GtkTextBuffer *buffer;
1590                 GtkTextIter start, end;
1591
1592                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1593                 gtk_text_buffer_get_start_iter (buffer, &start);
1594                 gtk_text_buffer_get_end_iter (buffer, &end);
1595                 gtk_text_buffer_select_range (buffer, &start, &end);
1596         }
1597 }
1598
1599 void
1600 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
1601                                   GtkRadioAction *selected,
1602                                   ModestWindow *window)
1603 {
1604         gint value;
1605
1606         value = gtk_radio_action_get_current_value (selected);
1607         if (MODEST_IS_WINDOW (window)) {
1608                 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
1609         }
1610 }
1611
1612 void     modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
1613                                                         GtkRadioAction *selected,
1614                                                         ModestWindow *window)
1615 {
1616         TnyHeaderFlags flags;
1617         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1618
1619         flags = gtk_radio_action_get_current_value (selected);
1620         modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
1621 }
1622
1623 void     modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
1624                                                            GtkRadioAction *selected,
1625                                                            ModestWindow *window)
1626 {
1627         gint file_format;
1628
1629         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1630
1631         file_format = gtk_radio_action_get_current_value (selected);
1632         modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
1633 }
1634
1635
1636 void     
1637 modest_ui_actions_on_zoom_plus (GtkAction *action,
1638                                 ModestWindow *window)
1639 {
1640         g_return_if_fail (MODEST_IS_WINDOW (window));
1641
1642         modest_window_zoom_plus (MODEST_WINDOW (window));
1643 }
1644
1645 void     
1646 modest_ui_actions_on_zoom_minus (GtkAction *action,
1647                                  ModestWindow *window)
1648 {
1649         g_return_if_fail (MODEST_IS_WINDOW (window));
1650
1651         modest_window_zoom_minus (MODEST_WINDOW (window));
1652 }
1653
1654 void     
1655 modest_ui_actions_on_toggle_fullscreen    (GtkToggleAction *toggle,
1656                                            ModestWindow *window)
1657 {
1658         ModestWindowMgr *mgr;
1659         gboolean fullscreen, active;
1660         g_return_if_fail (MODEST_IS_WINDOW (window));
1661
1662         mgr = modest_runtime_get_window_mgr ();
1663
1664         active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
1665         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1666
1667         if (active != fullscreen) {
1668                 modest_window_mgr_set_fullscreen_mode (mgr, active);
1669                 gtk_window_present (GTK_WINDOW (window));
1670         }
1671 }
1672
1673 void
1674 modest_ui_actions_on_change_fullscreen (GtkAction *action,
1675                                         ModestWindow *window)
1676 {
1677         ModestWindowMgr *mgr;
1678         gboolean fullscreen;
1679
1680         g_return_if_fail (MODEST_IS_WINDOW (window));
1681
1682         mgr = modest_runtime_get_window_mgr ();
1683         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1684         modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
1685
1686         gtk_window_present (GTK_WINDOW (window));
1687 }
1688
1689 /*
1690  * Show the header details in a ModestDetailsDialog widget
1691  */
1692 static void
1693 show_header_details (TnyHeader *header, 
1694                      GtkWindow *window)
1695 {
1696         GtkWidget *dialog;
1697         
1698         /* Create dialog */
1699         dialog = modest_details_dialog_new_with_header (window, header);
1700
1701         /* Run dialog */
1702         gtk_widget_show_all (dialog);
1703         gtk_dialog_run (GTK_DIALOG (dialog));
1704
1705         gtk_widget_destroy (dialog);
1706 }
1707
1708 /*
1709  * Show the folder details in a ModestDetailsDialog widget
1710  */
1711 static void
1712 show_folder_details (TnyFolder *folder, 
1713                      GtkWindow *window)
1714 {
1715         GtkWidget *dialog;
1716         
1717         /* Create dialog */
1718         dialog = modest_details_dialog_new_with_folder (window, folder);
1719
1720         /* Run dialog */
1721         gtk_widget_show_all (dialog);
1722         gtk_dialog_run (GTK_DIALOG (dialog));
1723
1724         gtk_widget_destroy (dialog);
1725 }
1726
1727
1728 void     
1729 modest_ui_actions_on_details (GtkAction *action, 
1730                               ModestWindow *win)
1731 {
1732         TnyList * headers_list;
1733         TnyIterator *iter;
1734         TnyHeader *header;              
1735
1736         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1737                 TnyMsg *msg;
1738
1739                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
1740                 if (!msg) {
1741                         return;
1742                 } else {
1743                         headers_list = get_selected_headers (win);
1744                         if (!headers_list)
1745                                 return;
1746
1747                         iter = tny_list_create_iterator (headers_list);
1748
1749                         header = TNY_HEADER (tny_iterator_get_current (iter));
1750                         show_header_details (header, GTK_WINDOW (win));
1751                         g_object_unref (header);
1752
1753                         g_object_unref (iter);
1754                 }
1755         } else if (MODEST_IS_MAIN_WINDOW (win)) {
1756                 GtkWidget *folder_view, *header_view;
1757
1758                 /* Check which widget has the focus */
1759                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1760                                                                     MODEST_WIDGET_TYPE_FOLDER_VIEW);
1761                 if (gtk_widget_is_focus (folder_view)) {
1762                         TnyFolder *folder;
1763
1764                         folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1765
1766                         /* Show only when it's a folder */
1767                         if (!folder || !TNY_IS_FOLDER (folder))
1768                                 return;
1769
1770                         show_folder_details (folder, GTK_WINDOW (win));
1771
1772                 } else {
1773                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1774                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
1775                         if (!gtk_widget_is_focus (header_view))
1776                                 return;
1777
1778                         headers_list = get_selected_headers (win);
1779                         if (!headers_list)
1780                                 return;
1781
1782                         iter = tny_list_create_iterator (headers_list);
1783                         while (!tny_iterator_is_done (iter)) {
1784
1785                                 header = TNY_HEADER (tny_iterator_get_current (iter));
1786                                 show_header_details (header, GTK_WINDOW (win));
1787                                 g_object_unref (header);
1788
1789                                 tny_iterator_next (iter);
1790                         }
1791                         g_object_unref (iter);
1792                 }
1793         }
1794 }
1795
1796 void     
1797 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
1798                                      ModestMsgEditWindow *window)
1799 {
1800         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1801
1802         modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
1803 }
1804
1805 void     
1806 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
1807                                       ModestMsgEditWindow *window)
1808 {
1809         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1810
1811         modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
1812 }
1813
1814 void
1815 modest_ui_actions_toggle_folders_view (GtkAction *action, 
1816                                        ModestMainWindow *main_window)
1817 {
1818         ModestConf *conf;
1819         
1820         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1821
1822         conf = modest_runtime_get_conf ();
1823         
1824         if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
1825                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
1826         else
1827                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
1828 }
1829
1830 void 
1831 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle, 
1832                                      ModestWindow *window)
1833 {
1834         gboolean active, fullscreen = FALSE;
1835         ModestWindowMgr *mgr;
1836
1837         active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
1838
1839         /* Check if we want to toggle the toolbar vuew in fullscreen
1840            or normal mode */
1841         if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)), 
1842                      "ViewShowToolbarFullScreen")) {
1843                 fullscreen = TRUE;
1844         }
1845
1846         /* Toggle toolbar */
1847         mgr = modest_runtime_get_window_mgr ();
1848         modest_window_mgr_show_toolbars (mgr, active, fullscreen);
1849 }
1850
1851 void     
1852 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
1853                                            ModestMsgEditWindow *window)
1854 {
1855         modest_msg_edit_window_select_font (window);
1856 }
1857
1858 void
1859 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
1860                                                   const gchar *display_name,
1861                                                   GtkWindow *window)
1862 {
1863         /* Do not change the application name if the widget has not
1864            the focus. This callback could be called even if the folder
1865            view has not the focus, because the handled signal could be
1866            emitted when the folder view is redrawn */
1867         if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
1868                 if (display_name)
1869                         gtk_window_set_title (window, display_name);
1870                 else
1871                         gtk_window_set_title (window, " ");
1872         }
1873 }
1874
1875 void
1876 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
1877 {
1878         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1879         modest_msg_edit_window_select_contacts (window);
1880 }
1881
1882
1883 static GtkWidget*
1884 create_move_to_dialog (ModestWindow *win,
1885                        GtkWidget *folder_view,
1886                        GtkWidget **tree_view)
1887 {
1888         GtkWidget *dialog, *scroll;
1889
1890         dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
1891                                               GTK_WINDOW (win),
1892                                               GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
1893                                               GTK_STOCK_OK,
1894                                               GTK_RESPONSE_ACCEPT,
1895                                               GTK_STOCK_CANCEL,
1896                                               GTK_RESPONSE_REJECT,
1897                                               NULL);
1898
1899         /* Create scrolled window */
1900         scroll = gtk_scrolled_window_new (NULL, NULL);
1901         gtk_scrolled_window_set_policy  (GTK_SCROLLED_WINDOW (scroll),
1902                                          GTK_POLICY_AUTOMATIC,
1903                                          GTK_POLICY_AUTOMATIC);
1904
1905         /* Create folder view */
1906         *tree_view = modest_folder_view_new (NULL);
1907         gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
1908                                  gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
1909         gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
1910
1911         /* Add scroll to dialog */
1912         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), 
1913                             scroll, FALSE, FALSE, 0);
1914
1915         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1916
1917         return dialog;
1918 }
1919
1920 static void 
1921 modest_ui_actions_on_main_window_move_to (GtkAction *action, 
1922                                           ModestMainWindow *win)
1923 {
1924         GtkWidget *dialog, *folder_view, *tree_view = NULL;
1925         gint result;
1926         TnyFolderStore *folder_store;
1927         ModestMailOperation *mail_op = NULL;
1928
1929         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
1930
1931         /* Get the folder view */
1932         folder_view = modest_main_window_get_child_widget (win,
1933                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1934
1935         /* Create and run the dialog */
1936         dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
1937         result = gtk_dialog_run (GTK_DIALOG(dialog));
1938
1939         /* We do this to save an indentation level ;-) */
1940         if (result != GTK_RESPONSE_ACCEPT)
1941                 goto end;
1942
1943         folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
1944
1945         if (TNY_IS_ACCOUNT (folder_store))
1946                 goto end;
1947
1948         /* Create mail operation */
1949         mail_op = modest_mail_operation_new ();
1950         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
1951                                          mail_op);
1952
1953         /* Get folder or messages to transfer */
1954         if (gtk_widget_is_focus (folder_view)) {
1955                 TnyFolderStore *src_folder;
1956                 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1957
1958                 if (TNY_IS_FOLDER (src_folder))
1959                         modest_mail_operation_xfer_folder (mail_op, 
1960                                                            TNY_FOLDER (src_folder),
1961                                                            folder_store,
1962                                                            TRUE);
1963
1964                 /* Frees */
1965                 g_object_unref (G_OBJECT (src_folder));
1966         } else {
1967                 GtkWidget *header_view;
1968                 header_view = modest_main_window_get_child_widget (win,
1969                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
1970                 if (gtk_widget_is_focus (header_view)) {
1971                         TnyList *headers;
1972
1973                         headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
1974
1975                         /* Transfer messages */
1976                         modest_mail_operation_xfer_msgs (mail_op, 
1977                                                          headers,
1978                                                          TNY_FOLDER (folder_store),
1979                                                          TRUE);
1980                 }
1981         }
1982         g_object_unref (G_OBJECT (mail_op));    
1983         g_object_unref (folder_store);
1984
1985  end:
1986         gtk_widget_destroy (dialog);
1987 }
1988
1989 static void 
1990 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action, 
1991                                               ModestMsgViewWindow *win)
1992 {
1993         GtkWidget *dialog, *folder_view, *tree_view = NULL;
1994         gint result;
1995         ModestMailOperation *mail_op = NULL;
1996         ModestMainWindow *main_window;
1997         TnyMsg *msg;
1998         TnyHeader *header;
1999         TnyList *headers;
2000
2001         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2002                           MODEST_IS_MSG_VIEW_WINDOW (win));
2003
2004         /* Get the folder view */
2005         main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2006         folder_view = modest_main_window_get_child_widget (main_window,
2007                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2008
2009         /* Create and run the dialog */
2010         dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);  
2011         result = gtk_dialog_run (GTK_DIALOG(dialog));
2012
2013         /* We do this to save an indentation level ;-) */
2014         if (result == GTK_RESPONSE_ACCEPT) {
2015                 TnyFolderStore *folder_store;
2016
2017                 /* Create mail operation */
2018                 mail_op = modest_mail_operation_new ();
2019                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
2020                                                  mail_op);
2021
2022                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2023
2024                 /* Create header list */
2025                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2026                 header = tny_msg_get_header (msg);
2027                 headers = tny_simple_list_new ();
2028                 tny_list_prepend (headers, G_OBJECT (header));
2029                 g_object_unref (header);
2030                 g_object_unref (msg);
2031
2032                 /* Transfer current msg */
2033                 modest_mail_operation_xfer_msgs (mail_op, 
2034                                                  headers,
2035                                                  TNY_FOLDER (folder_store),
2036                                                  TRUE);
2037                 g_object_unref (G_OBJECT (mail_op));
2038                 g_object_unref (folder_store);
2039         }
2040         gtk_widget_destroy (dialog);
2041 }
2042
2043 void 
2044 modest_ui_actions_on_move_to (GtkAction *action, 
2045                               ModestWindow *win)
2046 {
2047         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2048                           MODEST_IS_MSG_VIEW_WINDOW (win));
2049
2050         if (MODEST_IS_MAIN_WINDOW (win)) 
2051                 modest_ui_actions_on_main_window_move_to (action, 
2052                                                           MODEST_MAIN_WINDOW (win));
2053         else
2054                 modest_ui_actions_on_msg_view_window_move_to (action, 
2055                                                               MODEST_MSG_VIEW_WINDOW (win));
2056 }