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