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