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