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