build fixes for gnome
[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-msg.h>
38 #include <modest-tny-account.h>
39 #include <modest-address-book.h>
40
41 #include "modest-ui-actions.h"
42
43 #include "modest-tny-platform-factory.h"
44 #include "modest-platform.h"
45
46 #include <widgets/modest-main-window.h>
47 #include <widgets/modest-msg-view-window.h>
48 #include <widgets/modest-account-view-window.h>
49 #include <widgets/modest-msg-view-details-dialog.h>
50
51 #include "modest-account-mgr-helpers.h"
52 #include "modest-mail-operation.h"
53
54 #ifdef MODEST_HAVE_EASYSETUP
55 #include "easysetup/modest-easysetup-wizard.h"
56 #endif /*MODEST_HAVE_EASYSETUP*/
57
58 #include <modest-widget-memory.h>
59 #include <tny-error.h>
60 #include <tny-simple-list.h>
61 #include <tny-msg-view.h>
62 #include <tny-device.h>
63
64
65 typedef struct _GetMsgAsyncHelper {
66         ModestWindow *window;
67         TnyIterator *iter;
68         GFunc func;
69         gpointer user_data;
70 } GetMsgAsyncHelper;
71
72 typedef enum _ReplyForwardAction {
73         ACTION_REPLY,
74         ACTION_REPLY_TO_ALL,
75         ACTION_FORWARD
76 } ReplyForwardAction;
77
78 typedef struct _ReplyForwardHelper {
79 guint reply_forward_type;
80         ReplyForwardAction action;
81         gchar *account_name;
82 } ReplyForwardHelper;
83
84
85 static void     reply_forward_func     (gpointer data, gpointer user_data);
86 static void     read_msg_func          (gpointer data, gpointer user_data);
87 static void     get_msg_cb             (TnyFolder *folder, TnyMsg *msg, GError **err, 
88                                         gpointer user_data);
89 static void     reply_forward          (ReplyForwardAction action, ModestWindow *win);
90 static void     modest_ui_actions_message_details_cb (gpointer msg_data, 
91                                                       gpointer helper_data);
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 KernelConcepts and Igalia\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         /* FIXME: save size of main window */
200 /*      save_sizes (main_window); */
201 /*      gtk_widget_destroy (GTK_WIDGET (win)); */
202         gtk_main_quit ();
203 }
204
205 void
206 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
207 {
208         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
209                 gtk_widget_destroy (GTK_WIDGET (win));
210         } else if (MODEST_IS_WINDOW (win)) {
211                 gtk_widget_destroy (GTK_WIDGET (win));
212         } else {
213                 g_return_if_reached ();
214         }
215 }
216
217 void
218 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
219 {
220         GtkClipboard *clipboard = NULL;
221         gchar *selection = NULL;
222
223         clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
224         selection = gtk_clipboard_wait_for_text (clipboard);
225
226         modest_address_book_add_address (selection);
227         g_free (selection);
228 }
229
230 void
231 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
232 {
233         GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr());
234                                                      
235         //gboolean accounts_exist = account_names != NULL;
236         g_slist_free (account_names);
237         
238         /* This is currently only implemented for Maemo,
239          * because it requires a providers preset file which is not publically available.
240          */
241 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
242         /* To test, while modest_account_mgr_account_names() is broken: accounts_exist = TRUE; */
243         if (!accounts_exist) {
244                 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
245                 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
246                 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
247                 gtk_dialog_run (GTK_DIALOG (wizard));
248                 gtk_widget_destroy (GTK_WIDGET (wizard));
249         }
250         else
251         {
252                 /* Show the list of accounts: */
253                 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
254                 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
255                 gtk_dialog_run (account_win);
256                 gtk_widget_destroy (GTK_WIDGET(account_win));
257         }
258 #else
259    GtkWidget *dialog, *label;
260    
261    /* Create the widgets */
262    
263    dialog = gtk_dialog_new_with_buttons ("Message",
264                                          GTK_WINDOW(win),
265                                          GTK_DIALOG_DESTROY_WITH_PARENT,
266                                          GTK_STOCK_OK,
267                                          GTK_RESPONSE_NONE,
268                                          NULL);
269    label = gtk_label_new ("Hello World!");
270    
271    /* Ensure that the dialog box is destroyed when the user responds. */
272    
273    g_signal_connect_swapped (dialog, "response", 
274                              G_CALLBACK (gtk_widget_destroy),
275                              dialog);
276
277    /* Add the label, and show everything we've added to the dialog. */
278
279    gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
280                       label);
281    gtk_widget_show_all (dialog);
282 #endif /* MODEST_PLATFORM_MAEMO */
283 }
284
285 void
286 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
287 {
288         ModestWindow *msg_win;
289         TnyMsg *msg = NULL;
290         TnyFolder *folder = NULL;
291         gchar *account_name = NULL;
292         gchar *from_str = NULL;
293         GError *err = NULL;
294         TnyAccount *account;
295         ModestWindowMgr *mgr;
296         
297         account_name = g_strdup(modest_window_get_active_account (win));
298         if (!account_name)
299                 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
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
311         msg    = modest_tny_msg_new ("", from_str, "", "", "", "", NULL);
312         if (!msg) {
313                 g_printerr ("modest: failed to create new msg\n");
314                 goto cleanup;
315         }
316         
317         folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
318         if (!folder) {
319                 g_printerr ("modest: failed to find Drafts folder\n");
320                 goto cleanup;
321         }
322         
323         tny_folder_add_msg (folder, msg, &err);
324         if (err) {
325                 g_printerr ("modest: error adding msg to Drafts folder: %s",
326                             err->message);
327                 g_error_free (err);
328                 goto cleanup;
329         }
330
331         /* Create and register edit window */
332         msg_win = modest_msg_edit_window_new (msg, account_name);
333         mgr = modest_runtime_get_window_mgr ();
334         modest_window_mgr_register_window (mgr, msg_win);
335
336         if (win)
337                 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
338                                               GTK_WINDOW (win));        
339         gtk_widget_show_all (GTK_WIDGET (msg_win));
340
341 cleanup:
342         g_free (account_name);
343         g_free (from_str);
344         if (account)
345                 g_object_unref (G_OBJECT(account));
346         if (msg)
347                 g_object_unref (G_OBJECT(msg));
348         if (folder)
349                 g_object_unref (G_OBJECT(folder));
350 }
351
352
353 void
354 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
355 {
356         modest_runtime_not_implemented (GTK_WINDOW(win)); /* FIXME */
357 }
358
359
360
361 static void
362 reply_forward_func (gpointer data, gpointer user_data)
363 {
364         TnyMsg *msg, *new_msg;
365         GetMsgAsyncHelper *helper;
366         ReplyForwardHelper *rf_helper;
367         ModestWindow *msg_win;
368         ModestEditType edit_type;
369         gchar *from;
370         GError *err = NULL;
371         TnyFolder *folder = NULL;
372         TnyAccount *account = NULL;
373         ModestWindowMgr *mgr;
374         
375         msg = TNY_MSG (data);
376         helper = (GetMsgAsyncHelper *) user_data;
377         rf_helper = (ReplyForwardHelper *) helper->user_data;
378
379         from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
380                                                    rf_helper->account_name);
381         /* Create reply mail */
382         switch (rf_helper->action) {
383         case ACTION_REPLY:
384                 new_msg = 
385                         modest_tny_msg_create_reply_msg (msg,  from, 
386                                                          rf_helper->reply_forward_type,
387                                                          MODEST_TNY_MSG_REPLY_MODE_SENDER);
388                 break;
389         case ACTION_REPLY_TO_ALL:
390                 new_msg = 
391                         modest_tny_msg_create_reply_msg (msg, from, rf_helper->reply_forward_type,
392                                                          MODEST_TNY_MSG_REPLY_MODE_ALL);
393                 edit_type = MODEST_EDIT_TYPE_REPLY;
394                 break;
395         case ACTION_FORWARD:
396                 new_msg = 
397                         modest_tny_msg_create_forward_msg (msg, from, rf_helper->reply_forward_type);
398                 edit_type = MODEST_EDIT_TYPE_FORWARD;
399                 break;
400         default:
401                 g_return_if_reached ();
402                 return;
403         }
404
405         if (!new_msg) {
406                 g_printerr ("modest: failed to create message\n");
407                 goto cleanup;
408         }
409
410         account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
411                                                                        rf_helper->account_name,
412                                                                        TNY_ACCOUNT_TYPE_STORE);
413         if (!account) {
414                 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
415                 goto cleanup;
416         }
417
418         folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
419         if (!folder) {
420                 g_printerr ("modest: failed to find Drafts folder\n");
421                 goto cleanup;
422         }
423         
424         tny_folder_add_msg (folder, msg, &err);
425         if (err) {
426                 g_printerr ("modest: error adding msg to Drafts folder: %s",
427                             err->message);
428                 g_error_free (err);
429                 goto cleanup;
430         }       
431
432         /* Create and register the windows */                   
433         msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
434         mgr = modest_runtime_get_window_mgr ();
435         modest_window_mgr_register_window (mgr, msg_win);
436
437         /* Show edit window */
438         gtk_widget_show_all (GTK_WIDGET (msg_win));
439
440 cleanup:
441         if (new_msg)
442                 g_object_unref (G_OBJECT (new_msg));
443         if (folder)
444                 g_object_unref (G_OBJECT (folder));
445         if (account)
446                 g_object_unref (G_OBJECT (account));
447         
448         g_free (rf_helper->account_name);
449         g_slice_free (ReplyForwardHelper, rf_helper);
450 }
451 /*
452  * Common code for the reply and forward actions
453  */
454 static void
455 reply_forward (ReplyForwardAction action, ModestWindow *win)
456 {
457         TnyList *header_list;
458         guint reply_forward_type;
459         TnyHeader *header;
460         TnyFolder *folder;
461         GetMsgAsyncHelper *helper;
462         ReplyForwardHelper *rf_helper;
463         
464         g_return_if_fail (MODEST_IS_WINDOW(win));
465
466         header_list = get_selected_headers (win);
467         if (!header_list)
468                 return;
469         
470         reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (),
471                                                   (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
472                                                   NULL);
473         /* We assume that we can only select messages of the
474            same folder and that we reply all of them from the
475            same account. In fact the interface currently only
476            allows single selection */
477         
478         /* Fill helpers */
479         rf_helper = g_slice_new0 (ReplyForwardHelper);
480         rf_helper->reply_forward_type = reply_forward_type;
481         rf_helper->action = action;
482
483         rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
484         if (!rf_helper->account_name)
485                 rf_helper->account_name =
486                         modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
487
488         helper = g_slice_new0 (GetMsgAsyncHelper);
489         helper->window = win;
490         helper->func = reply_forward_func;
491         helper->iter = tny_list_create_iterator (header_list);
492         helper->user_data = rf_helper;
493
494         if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
495                 TnyMsg *msg;
496                 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
497                 if (!msg) {
498                         g_printerr ("modest: no message found\n");
499                         return;
500                 } else
501                         reply_forward_func (msg, helper);
502         } else {
503                 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
504                 folder = tny_header_get_folder (header);
505                 if (folder) {
506                         /* The callback will call it per each header */
507                         tny_folder_get_msg_async (folder, header, get_msg_cb, helper);
508                         g_object_unref (G_OBJECT (folder));
509                 } else 
510                         g_printerr ("modest: no folder for header\n");
511                 
512                 /* Clean */
513                 g_object_unref (G_OBJECT (header));
514         }
515 }
516
517
518 void
519 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
520 {
521         g_return_if_fail (MODEST_IS_WINDOW(win));
522
523         reply_forward (ACTION_REPLY, win);
524 }
525
526 void
527 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
528 {
529         g_return_if_fail (MODEST_IS_WINDOW(win));
530
531         reply_forward (ACTION_FORWARD, win);
532 }
533
534 void
535 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
536 {
537         g_return_if_fail (MODEST_IS_WINDOW(win));
538
539         reply_forward (ACTION_REPLY_TO_ALL, win);
540 }
541
542 void 
543 modest_ui_actions_on_next (GtkAction *action, 
544                            ModestWindow *window)
545 {
546         if (MODEST_IS_MAIN_WINDOW (window)) {
547                 GtkWidget *header_view;
548
549                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
550                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
551                 if (!header_view)
552                         return;
553         
554                 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view)); 
555         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
556                 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
557         } else {
558                 g_return_if_reached ();
559         }
560 }
561
562 void 
563 modest_ui_actions_on_prev (GtkAction *action, 
564                            ModestWindow *window)
565 {
566         g_return_if_fail (MODEST_IS_WINDOW(window));
567
568         if (MODEST_IS_MAIN_WINDOW (window)) {
569                 GtkWidget *header_view;
570                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
571                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
572                 if (!header_view)
573                         return;
574                 
575                 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view)); 
576         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
577                 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
578         } else {
579                 g_return_if_reached ();
580         }
581 }
582
583
584 static gboolean
585 action_send (const gchar* account_name)
586 {
587         TnyAccount *tny_account;
588         ModestTnySendQueue *send_queue;
589
590         g_return_val_if_fail (account_name, FALSE);
591
592         tny_account = 
593                 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
594                                                                      account_name,
595                                                                      TNY_ACCOUNT_TYPE_TRANSPORT);
596         if (!tny_account) {
597                 g_printerr ("modest: cannot get tny transport account for %s\n", account_name);
598                 return FALSE;
599         }
600         send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(tny_account));
601         if (!send_queue) {
602                 g_object_unref (G_OBJECT(tny_account));
603                 g_printerr ("modest: cannot get send queue for %s\n", account_name);
604                 return FALSE;
605         }
606         
607         //modest_tny_send_queue_flush (send_queue);
608
609         g_object_unref (G_OBJECT(send_queue));
610         g_object_unref (G_OBJECT(tny_account));
611
612         return TRUE;
613 }
614
615
616 static gboolean
617 action_receive (const gchar* account_name)
618 {
619         TnyAccount *tny_account;
620         ModestMailOperation *mail_op;
621
622         g_return_val_if_fail (account_name, FALSE);
623
624         tny_account = 
625                 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
626                                                                      account_name,
627                                                                      TNY_ACCOUNT_TYPE_STORE);
628         if (!tny_account) {
629                 g_printerr ("modest: cannot get tny store account for %s\n", account_name);
630                 return FALSE;
631         }
632
633         /* Create the mail operation */
634         mail_op = modest_mail_operation_new ();
635         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
636         modest_mail_operation_update_account (mail_op, TNY_STORE_ACCOUNT(tny_account));
637         g_object_unref (G_OBJECT(tny_account));
638         g_object_unref (G_OBJECT (mail_op));
639                 
640         return TRUE;
641 }
642
643
644
645 void
646 modest_ui_actions_on_send_receive (GtkAction *action,  ModestWindow *win)
647 {
648         gchar *account_name;
649         
650         account_name =
651                 g_strdup(modest_window_get_active_account(MODEST_WINDOW(win)));
652         if (!account_name)
653                 account_name  = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
654         if (!account_name) {
655                 g_printerr ("modest: cannot get account\n");
656                 return;
657         }
658
659         if (!action_send(account_name))
660                 g_printerr ("modest: failed to send\n");
661         if (!action_receive(account_name))
662                 g_printerr ("modest: failed to receive\n");
663 }
664
665
666
667 void
668 modest_ui_actions_toggle_view (GtkAction *action, ModestMainWindow *main_window)
669 {
670         ModestConf *conf;
671         GtkWidget *header_view;
672         
673         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
674
675         header_view = modest_main_window_get_child_widget (main_window,
676                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
677         if (!header_view)
678                 return;
679
680         conf = modest_runtime_get_conf ();
681         
682         /* what is saved/restored is depending on the style; thus; we save with
683          * old style, then update the style, and restore for this new style
684          */
685         modest_widget_memory_save (conf, G_OBJECT(header_view), "header-view");
686         
687         if (modest_header_view_get_style
688             (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
689                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
690                                               MODEST_HEADER_VIEW_STYLE_TWOLINES);
691         else
692                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
693                                               MODEST_HEADER_VIEW_STYLE_DETAILS);
694
695         modest_widget_memory_restore (conf, G_OBJECT(header_view),
696                                       "header-view");
697 }
698
699
700
701 /*
702  * Marks a message as read and passes it to the msg preview widget
703  */
704 static void
705 read_msg_func (gpointer data, gpointer user_data)
706 {
707         TnyMsg *msg;
708         TnyHeader *header;
709         GetMsgAsyncHelper *helper;
710         TnyHeaderFlags header_flags;
711         GtkWidget *msg_preview;
712         
713         msg = TNY_MSG (data);
714         helper = (GetMsgAsyncHelper *) user_data;
715
716         msg_preview = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (helper->window),
717                                                            MODEST_WIDGET_TYPE_MSG_PREVIEW);
718         if (!msg_preview)
719                 return;
720         
721         header = TNY_HEADER (tny_iterator_get_current (helper->iter));
722         header_flags = tny_header_get_flags (header);
723         tny_header_set_flags (header, header_flags | TNY_HEADER_FLAG_SEEN);
724         g_object_unref (G_OBJECT (header));
725
726         /* Set message on msg view */
727         modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), msg);
728 }
729
730 /*
731  * This function is a generic handler for the tny_folder_get_msg_async
732  * call. It expects as user_data a #GetMsgAsyncHelper. This helper
733  * contains a user provided function that is called inside this
734  * method. This will allow us to use this callback in many different
735  * places. This callback performs the common actions for the
736  * get_msg_async call, more specific actions will be done by the user
737  * function
738  */
739 static void
740 get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data)
741 {
742         GetMsgAsyncHelper *helper;
743
744         helper = (GetMsgAsyncHelper *) user_data;
745
746         if ((*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) || !msg) {
747                 modest_ui_actions_on_item_not_found (NULL,
748                                                      MODEST_ITEM_TYPE_MESSAGE,
749                                                      helper->window);
750                 return;
751         }
752
753         /* Call user function */
754         helper->func (msg, user_data);
755
756         /* Process next element (if exists) */
757         tny_iterator_next (helper->iter);
758         if (tny_iterator_is_done (helper->iter)) {
759                 TnyList *headers;
760                 headers = tny_iterator_get_list (helper->iter);
761                 /* Free resources */
762                 g_object_unref (G_OBJECT (headers));
763                 g_object_unref (G_OBJECT (helper->iter));
764                 g_slice_free (GetMsgAsyncHelper, helper);
765         } else {
766                 TnyHeader *header;
767                 header = TNY_HEADER (tny_iterator_get_current (helper->iter)); 
768                 tny_folder_get_msg_async (folder, header,                         
769                                           get_msg_cb, helper);
770                 g_object_unref (G_OBJECT(header));
771         }
772 }
773
774 void 
775 modest_ui_actions_on_header_selected (ModestHeaderView *folder_view, 
776                                       TnyHeader *header,
777                                       ModestMainWindow *main_window)
778 {
779         GtkWidget *msg_preview;
780         TnyFolder *folder;
781         GetMsgAsyncHelper *helper;
782         TnyList *list;
783
784         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
785         
786         msg_preview = modest_main_window_get_child_widget(main_window,
787                                                           MODEST_WIDGET_TYPE_MSG_PREVIEW);
788         if (!msg_preview)
789                 return;
790         
791         /* when there's no header, clear the msgview */
792         if (!header) {
793                 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), NULL);
794                 return;
795         }
796
797         folder = tny_header_get_folder (TNY_HEADER(header));
798
799         /* Create list */
800         list = tny_simple_list_new ();
801         tny_list_prepend (list, G_OBJECT (header));
802
803         /* Fill helper data */
804         helper = g_slice_new0 (GetMsgAsyncHelper);
805         helper->window = MODEST_WINDOW (main_window);
806         helper->iter = tny_list_create_iterator (list);
807         helper->func = read_msg_func;
808
809         tny_folder_get_msg_async (TNY_FOLDER(folder),
810                                   header, get_msg_cb,
811                                   helper);
812
813         /* Frees */
814         g_object_unref (G_OBJECT (folder));
815 }
816
817
818
819 void 
820 modest_ui_actions_on_header_activated (ModestHeaderView *folder_view, TnyHeader *header,
821                                        ModestMainWindow *main_window)
822 {
823         ModestWindow *win;
824         TnyFolder *folder = NULL;
825         TnyMsg    *msg    = NULL;
826         gchar *account    = NULL;
827         GtkTreeModel *model = NULL;
828         GtkTreeSelection *sel = NULL;
829         GtkTreeIter iter;
830         ModestWindowMgr *mgr;
831         
832         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
833         
834         if (!header)
835                 return;
836
837         folder = tny_header_get_folder (header);
838         if (!folder) {
839                 g_printerr ("modest: cannot get folder for header\n");
840                 goto cleanup;
841         }
842
843         /* FIXME: make async?; check error  */
844         msg = tny_folder_get_msg (folder, header, NULL);
845         if (!msg) {
846                 g_printerr ("modest: cannot get msg for header\n");
847                 goto cleanup;
848         }
849
850         account =  g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window)));
851         if (!account)
852                 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
853
854         /* Create and register message view window */   
855         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
856         if (gtk_tree_selection_get_selected (sel, &model, &iter)) {
857                 win = modest_msg_view_window_new_with_header_model (msg, account, model, iter);
858         } else {
859                 win = modest_msg_view_window_new (msg, account);
860         }
861         mgr = modest_runtime_get_window_mgr ();
862         modest_window_mgr_register_window (mgr, win);
863
864         gtk_window_set_transient_for (GTK_WINDOW (win),
865                                       GTK_WINDOW (main_window));
866
867         gtk_widget_show_all (GTK_WIDGET(win));
868         
869 cleanup:
870         g_free (account);
871         
872         if (folder)
873                 g_object_unref (G_OBJECT (folder));
874         if (msg)
875                 g_object_unref (G_OBJECT (msg));
876 }
877
878 void 
879 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
880                                                TnyFolder *folder, 
881                                                gboolean selected,
882                                                ModestMainWindow *main_window)
883 {
884         gchar *txt;
885         ModestConf *conf;
886         GtkWidget *header_view;
887         
888         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
889
890         header_view = modest_main_window_get_child_widget(main_window,
891                                                           MODEST_WIDGET_TYPE_HEADER_VIEW);
892         if (!header_view)
893                 return;
894         
895         conf = modest_runtime_get_conf ();
896
897         if (!selected) { /* the folder was unselected; save it's settings  */
898                 modest_widget_memory_save (conf, G_OBJECT (header_view), "header-view");
899                 gtk_window_set_title (GTK_WINDOW(main_window), "Modest");
900                 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
901         } else {  /* the folder was selected */
902                 if (folder) { /* folder may be NULL */
903                         guint num, unread;
904                         gchar *title;
905
906                         num    = tny_folder_get_all_count    (folder);
907                         unread = tny_folder_get_unread_count (folder);
908                         
909                         title = g_strdup_printf ("Modest: %s",
910                                                  tny_folder_get_name (folder));
911                         
912                         gtk_window_set_title (GTK_WINDOW(main_window), title);
913                         g_free (title);
914                         
915                         txt = g_strdup_printf (_("%d %s, %d unread"),
916                                                num, num==1 ? _("item") : _("items"), unread);           
917                         //gtk_label_set_label (GTK_LABEL(folder_info_label), txt);
918                         g_free (txt);
919                 }
920                 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), folder);
921                 modest_widget_memory_restore (conf, G_OBJECT(header_view),
922                                               "header-view");
923         }
924 }
925
926 void 
927 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
928                                      ModestWindow *win)
929 {
930         GtkWidget *dialog;
931         gchar *txt, *item;
932         gboolean online;
933
934         item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
935         
936         if (g_main_depth > 0)   
937                 gdk_threads_enter ();
938         online = tny_device_is_online (modest_runtime_get_device());
939
940         if (online) {
941                 /* already online -- the item is simply not there... */
942                 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
943                                                  GTK_DIALOG_MODAL,
944                                                  GTK_MESSAGE_WARNING,
945                                                  GTK_BUTTONS_OK,
946                                                  _("The %s you selected cannot be found"),
947                                                  item);
948                 gtk_dialog_run (GTK_DIALOG(dialog));
949         } else {
950                 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
951                                                       GTK_WINDOW (win),
952                                                       GTK_DIALOG_MODAL,
953                                                       GTK_STOCK_CANCEL,
954                                                       GTK_RESPONSE_REJECT,
955                                                       GTK_STOCK_OK,
956                                                       GTK_RESPONSE_ACCEPT,
957                                                       NULL);
958                 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
959                                          "Do you want to get online?"), item);
960                 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
961                                     gtk_label_new (txt), FALSE, FALSE, 0);
962                 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
963                 g_free (txt);
964
965                 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
966                 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
967 //                      tny_device_force_online (modest_runtime_get_device());
968                 }
969         }
970         gtk_widget_destroy (dialog);
971         if (g_main_depth > 0)   
972                 gdk_threads_leave ();
973 }
974
975 void
976 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
977                                      ModestWindow *win)
978 {
979         g_message ("%s %s", __FUNCTION__, link);
980 }       
981
982
983 void
984 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
985                                         ModestWindow *win)
986 {
987         modest_platform_activate_uri (link);
988 }
989
990 void
991 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
992                                           ModestWindow *win)
993 {
994         modest_platform_show_uri_popup (link);
995 }
996
997 void
998 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
999                                              ModestWindow *win)
1000 {
1001         g_message (__FUNCTION__);
1002         
1003 }
1004
1005 void
1006 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1007                                           const gchar *address,
1008                                           ModestWindow *win)
1009 {
1010         g_message ("%s %s", __FUNCTION__, address);
1011 }
1012
1013 void
1014 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1015 {
1016         TnyTransportAccount *transport_account;
1017         ModestMailOperation *mail_operation;
1018         MsgData *data;
1019         gchar *account_name, *from;
1020         ModestAccountMgr *account_mgr;
1021
1022         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1023         
1024         data = modest_msg_edit_window_get_msg_data (edit_window);
1025
1026         /* FIXME: Code added just for testing. The final version will
1027            use the send queue provided by tinymail and some
1028            classifier */
1029         account_mgr = modest_runtime_get_account_mgr();
1030         account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1031         if (!account_name) 
1032                 account_name = modest_account_mgr_get_default_account (account_mgr);
1033         if (!account_name) {
1034                 g_printerr ("modest: no account found\n");
1035                 modest_msg_edit_window_free_msg_data (edit_window, data);
1036                 return;
1037         }
1038         transport_account =
1039                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1040                                       (modest_runtime_get_account_store(),
1041                                        account_name,
1042                                        TNY_ACCOUNT_TYPE_TRANSPORT));
1043         if (!transport_account) {
1044                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1045                 g_free (account_name);
1046                 modest_msg_edit_window_free_msg_data (edit_window, data);
1047                 return;
1048         }
1049         from = modest_account_mgr_get_from_string (account_mgr, account_name);
1050
1051         /* Create the mail operation */         
1052         mail_operation = modest_mail_operation_new ();
1053         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1054
1055         modest_mail_operation_send_new_mail (mail_operation,
1056                                              transport_account,
1057                                              from,
1058                                              data->to, 
1059                                              data->cc, 
1060                                              data->bcc,
1061                                              data->subject, 
1062                                              data->plain_body, 
1063                                              data->html_body,
1064                                              data->attachments);
1065         /* Frees */
1066         g_free (from);
1067         g_free (account_name);
1068         g_object_unref (G_OBJECT (transport_account));
1069         g_object_unref (G_OBJECT (mail_operation));
1070
1071         modest_msg_edit_window_free_msg_data (edit_window, data);
1072
1073         /* Save settings and close the window */
1074         gtk_widget_destroy (GTK_WIDGET (edit_window));
1075 }
1076
1077 void 
1078 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1079                                   ModestMsgEditWindow *window)
1080 {
1081         ModestMsgEditFormatState *format_state = NULL;
1082
1083         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1084         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1085
1086         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1087                 return;
1088
1089         format_state = modest_msg_edit_window_get_format_state (window);
1090         g_return_if_fail (format_state != NULL);
1091
1092         format_state->bold = gtk_toggle_action_get_active (action);
1093         modest_msg_edit_window_set_format_state (window, format_state);
1094         g_free (format_state);
1095         
1096 }
1097
1098 void 
1099 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1100                                      ModestMsgEditWindow *window)
1101 {
1102         ModestMsgEditFormatState *format_state = NULL;
1103
1104         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1105         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1106
1107         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1108                 return;
1109
1110         format_state = modest_msg_edit_window_get_format_state (window);
1111         g_return_if_fail (format_state != NULL);
1112
1113         format_state->italics = gtk_toggle_action_get_active (action);
1114         modest_msg_edit_window_set_format_state (window, format_state);
1115         g_free (format_state);
1116         
1117 }
1118
1119 void 
1120 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1121                                      ModestMsgEditWindow *window)
1122 {
1123         ModestMsgEditFormatState *format_state = NULL;
1124
1125         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1126         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1127
1128         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1129                 return;
1130
1131         format_state = modest_msg_edit_window_get_format_state (window);
1132         g_return_if_fail (format_state != NULL);
1133
1134         format_state->bullet = gtk_toggle_action_get_active (action);
1135         modest_msg_edit_window_set_format_state (window, format_state);
1136         g_free (format_state);
1137         
1138 }
1139
1140 void 
1141 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1142                                      GtkRadioAction *selected,
1143                                      ModestMsgEditWindow *window)
1144 {
1145         ModestMsgEditFormatState *format_state = NULL;
1146         GtkJustification value;
1147
1148         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1149
1150         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1151                 return;
1152
1153         value = gtk_radio_action_get_current_value (selected);
1154
1155         format_state = modest_msg_edit_window_get_format_state (window);
1156         g_return_if_fail (format_state != NULL);
1157
1158         format_state->justification = value;
1159         modest_msg_edit_window_set_format_state (window, format_state);
1160         g_free (format_state);
1161 }
1162
1163 void 
1164 modest_ui_actions_on_select_editor_color (GtkAction *action,
1165                                           ModestMsgEditWindow *window)
1166 {
1167         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1168         g_return_if_fail (GTK_IS_ACTION (action));
1169
1170         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1171                 return;
1172
1173         modest_msg_edit_window_select_color (window);
1174 }
1175
1176 void 
1177 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1178                                                      ModestMsgEditWindow *window)
1179 {
1180         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1181         g_return_if_fail (GTK_IS_ACTION (action));
1182
1183         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1184                 return;
1185
1186         modest_msg_edit_window_select_background_color (window);
1187 }
1188
1189 void 
1190 modest_ui_actions_on_insert_image (GtkAction *action,
1191                                    ModestMsgEditWindow *window)
1192 {
1193         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1194         g_return_if_fail (GTK_IS_ACTION (action));
1195
1196         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1197                 return;
1198
1199         modest_msg_edit_window_insert_image (window);
1200 }
1201
1202 /*
1203  * Shows a dialog with an entry that asks for some text. The returned
1204  * value must be freed by the caller. The dialog window title will be
1205  * set to @title.
1206  */
1207 static gchar *
1208 ask_for_folder_name (GtkWindow *parent_window,
1209                      const gchar *title)
1210 {
1211         GtkWidget *dialog, *entry;
1212         gchar *folder_name = NULL;
1213
1214         /* Ask for folder name */
1215         dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1216                                               parent_window,
1217                                               GTK_DIALOG_MODAL,
1218                                               GTK_STOCK_CANCEL,
1219                                               GTK_RESPONSE_REJECT,
1220                                               GTK_STOCK_OK,
1221                                               GTK_RESPONSE_ACCEPT,
1222                                               NULL);
1223         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1224                             gtk_label_new(title),
1225                             FALSE, FALSE, 0);
1226                 
1227         entry = gtk_entry_new_with_max_length (40);
1228         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1229                             entry,
1230                             TRUE, FALSE, 0);    
1231         
1232         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1233         
1234         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)         
1235                 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1236
1237         gtk_widget_destroy (dialog);
1238
1239         return folder_name;
1240 }
1241
1242 void 
1243 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1244 {
1245         TnyFolder *parent_folder;
1246         GtkWidget *folder_view;
1247         
1248         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1249
1250         folder_view = modest_main_window_get_child_widget (main_window,
1251                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1252         if (!folder_view)
1253                 return;
1254
1255         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1256         
1257         if (parent_folder) {
1258                 gchar *folder_name;
1259
1260                 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1261                                                    _("Please enter a name for the new folder"));
1262
1263                 if (folder_name != NULL && strlen (folder_name) > 0) {
1264                         TnyFolder *new_folder;
1265                         ModestMailOperation *mail_op;
1266
1267                         mail_op = modest_mail_operation_new ();
1268                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
1269                                                          mail_op);
1270
1271                         new_folder = modest_mail_operation_create_folder (mail_op,
1272                                                                           TNY_FOLDER_STORE (parent_folder),
1273                                                                           (const gchar *) folder_name);
1274                         if (new_folder) 
1275                                 g_object_unref (new_folder);
1276                         g_object_unref (mail_op);
1277                         g_free (folder_name);
1278                 }
1279                 g_object_unref (parent_folder);
1280         }
1281 }
1282
1283 void 
1284 modest_ui_actions_on_rename_folder (GtkAction *action,
1285                                      ModestMainWindow *main_window)
1286 {
1287         TnyFolder *folder;
1288         GtkWidget *folder_view;
1289         
1290         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1291
1292         folder_view = modest_main_window_get_child_widget (main_window,
1293                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1294         if (!folder_view)
1295                 return;
1296         
1297         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1298         
1299         if (folder) {
1300                 gchar *folder_name;
1301                 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1302                                                    _("Please enter a new name for the folder"));
1303
1304                 if (folder_name != NULL && strlen (folder_name) > 0) {
1305                         ModestMailOperation *mail_op;
1306
1307                         mail_op = modest_mail_operation_new ();
1308                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1309                                                          mail_op);
1310
1311                         modest_mail_operation_rename_folder (mail_op,
1312                                                              folder,
1313                                                              (const gchar *) folder_name);
1314
1315                         g_object_unref (mail_op);
1316                         g_free (folder_name);
1317                 }
1318                 g_object_unref (folder);
1319         }
1320 }
1321
1322 static void
1323 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash) 
1324 {
1325         TnyFolder *folder;
1326         ModestMailOperation *mail_op;
1327         GtkWidget *folder_view;
1328         
1329         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1330
1331         folder_view = modest_main_window_get_child_widget (main_window,
1332                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1333         if (!folder_view)
1334                 return;
1335
1336         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1337         
1338         mail_op = modest_mail_operation_new ();
1339         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1340                                          mail_op);
1341         modest_mail_operation_remove_folder (mail_op, folder, move_to_trash);
1342
1343         g_object_unref (G_OBJECT (mail_op));
1344         g_object_unref (G_OBJECT (folder));
1345 }
1346
1347 void 
1348 modest_ui_actions_on_delete_folder (GtkAction *action,
1349                                      ModestMainWindow *main_window)
1350 {
1351         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1352
1353         delete_folder (main_window, FALSE);
1354 }
1355
1356 void 
1357 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1358 {
1359         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1360         
1361         delete_folder (main_window, TRUE);
1362 }
1363
1364 void
1365 modest_ui_actions_on_password_requested (TnyAccountStore *account_store, 
1366                                          const gchar* account_name,
1367                                          gchar **password, 
1368                                          gboolean *cancel, 
1369                                          gboolean *remember,
1370                                          ModestMainWindow *main_window)
1371 {
1372         gchar *txt;
1373         GtkWidget *dialog, *entry, *remember_pass_check;
1374
1375         dialog = gtk_dialog_new_with_buttons (_("Password requested"),
1376                                               NULL,
1377                                               GTK_DIALOG_MODAL,
1378                                               GTK_STOCK_CANCEL,
1379                                               GTK_RESPONSE_REJECT,
1380                                               GTK_STOCK_OK,
1381                                               GTK_RESPONSE_ACCEPT,
1382                                               NULL);
1383         gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1384         
1385         txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
1386         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1387                             FALSE, FALSE, 0);
1388         g_free (txt);
1389
1390         entry = gtk_entry_new_with_max_length (40);
1391         gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
1392         gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
1393         
1394         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
1395                             TRUE, FALSE, 0);    
1396
1397         remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1398         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1399                             TRUE, FALSE, 0);
1400
1401         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1402         
1403         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1404                 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
1405                 *cancel   = FALSE;
1406         } else {
1407                 *password = NULL;
1408                 *cancel   = TRUE;
1409         }
1410
1411         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1412                 *remember = TRUE;
1413         else
1414                 *remember = FALSE;
1415
1416         gtk_widget_destroy (dialog);
1417 }
1418
1419 void
1420 modest_ui_actions_on_cut (GtkAction *action,
1421                           ModestWindow *window)
1422 {
1423         GtkWidget *focused_widget;
1424
1425         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1426         if (GTK_IS_EDITABLE (focused_widget)) {
1427                 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1428         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1429                 GtkTextBuffer *buffer;
1430                 GtkClipboard *clipboard;
1431
1432                 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1433                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1434                 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1435         }
1436 }
1437
1438 void
1439 modest_ui_actions_on_copy (GtkAction *action,
1440                            ModestWindow *window)
1441 {
1442         GtkClipboard *clipboard;
1443         GtkWidget *focused_widget;
1444
1445         clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1446         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1447         if (GTK_IS_LABEL (focused_widget)) {
1448                 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1449         } else if (GTK_IS_EDITABLE (focused_widget)) {
1450                 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1451         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1452                 GtkTextBuffer *buffer;
1453
1454                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1455                 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1456         }
1457 }
1458
1459 void
1460 modest_ui_actions_on_paste (GtkAction *action,
1461                             ModestWindow *window)
1462 {
1463         GtkWidget *focused_widget;
1464
1465         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1466         if (GTK_IS_EDITABLE (focused_widget)) {
1467                 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1468         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1469                 GtkTextBuffer *buffer;
1470                 GtkClipboard *clipboard;
1471
1472                 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1473                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1474                 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1475         }
1476 }
1477
1478 void
1479 modest_ui_actions_on_select_all (GtkAction *action,
1480                                  ModestWindow *window)
1481 {
1482         GtkWidget *focused_widget;
1483
1484         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1485         if (GTK_IS_LABEL (focused_widget)) {
1486                 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1487         } else if (GTK_IS_EDITABLE (focused_widget)) {
1488                 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1489         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1490                 GtkTextBuffer *buffer;
1491                 GtkTextIter start, end;
1492
1493                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1494                 gtk_text_buffer_get_start_iter (buffer, &start);
1495                 gtk_text_buffer_get_end_iter (buffer, &end);
1496                 gtk_text_buffer_select_range (buffer, &start, &end);
1497         }
1498 }
1499
1500 void
1501 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
1502                                   GtkRadioAction *selected,
1503                                   ModestWindow *window)
1504 {
1505         gint value;
1506
1507         value = gtk_radio_action_get_current_value (selected);
1508         if (MODEST_IS_WINDOW (window)) {
1509                 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
1510         }
1511 }
1512
1513 void     
1514 modest_ui_actions_on_toggle_fullscreen    (GtkToggleAction *toggle,
1515                                            ModestWindow *window)
1516 {
1517         g_return_if_fail (MODEST_IS_WINDOW (window));
1518
1519         if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle))) {
1520                 gtk_window_fullscreen (GTK_WINDOW (window));
1521         } else {
1522                 gtk_window_unfullscreen (GTK_WINDOW (window));
1523         }
1524 }
1525
1526 static void
1527 modest_ui_actions_message_details_cb (gpointer msg_data, 
1528                                       gpointer helper_data)
1529 {
1530         GtkWidget *dialog;
1531         TnyMsg *msg = (TnyMsg *) msg_data;
1532         TnyHeader *header;
1533         GetMsgAsyncHelper *helper = (GetMsgAsyncHelper *) helper_data;
1534         
1535         header = tny_msg_get_header (msg);
1536         
1537         dialog = modest_msg_view_details_dialog_new (GTK_WINDOW (helper->window), header);
1538         g_object_unref (header);
1539         gtk_widget_show_all (dialog);
1540
1541         gtk_dialog_run (GTK_DIALOG (dialog));
1542
1543         gtk_widget_destroy (dialog);
1544 }
1545
1546 void     
1547 modest_ui_actions_on_message_details (GtkAction *action, 
1548                                       ModestWindow *win)
1549 {
1550         TnyList * headers_list;
1551         GetMsgAsyncHelper *helper;
1552
1553         headers_list = get_selected_headers (win);
1554         if (!headers_list)
1555                 return;
1556
1557         helper = g_slice_new0 (GetMsgAsyncHelper);
1558         helper->window = win;
1559         helper->func = modest_ui_actions_message_details_cb;
1560         helper->iter = tny_list_create_iterator (headers_list);
1561         helper->user_data = NULL;
1562
1563         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1564                 TnyMsg *msg;
1565
1566                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
1567                 if (!msg)
1568                         return;
1569                 else {
1570                         modest_ui_actions_message_details_cb (msg, helper);
1571                 }
1572         } else {
1573                 /* here we should add an implementation to run the message details dialog
1574                    from the main window */
1575                 g_return_if_reached ();
1576         }
1577 }