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