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