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