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