remove subcontractor name because integration won't work otherwise
[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-folder.h>
38 #include <modest-tny-msg.h>
39 #include <modest-tny-account.h>
40 #include <modest-address-book.h>
41
42 #include "modest-ui-actions.h"
43
44 #include "modest-tny-platform-factory.h"
45 #include "modest-platform.h"
46
47 #include <widgets/modest-main-window.h>
48 #include <widgets/modest-msg-view-window.h>
49 #include <widgets/modest-account-view-window.h>
50 #include <widgets/modest-details-dialog.h>
51
52 #include "modest-account-mgr-helpers.h"
53 #include "modest-mail-operation.h"
54 #include "modest-text-utils.h"
55
56 #ifdef MODEST_HAVE_EASYSETUP
57 #include "easysetup/modest-easysetup-wizard.h"
58 #endif /*MODEST_HAVE_EASYSETUP*/
59
60 #include <modest-widget-memory.h>
61 #include <tny-error.h>
62 #include <tny-simple-list.h>
63 #include <tny-msg-view.h>
64 #include <tny-device.h>
65
66 typedef struct _GetMsgAsyncHelper {
67         ModestWindow *window;
68         TnyIterator *iter;
69         GFunc func;
70         gpointer user_data;
71 } GetMsgAsyncHelper;
72
73 typedef enum _ReplyForwardAction {
74         ACTION_REPLY,
75         ACTION_REPLY_TO_ALL,
76         ACTION_FORWARD
77 } ReplyForwardAction;
78
79 typedef struct _ReplyForwardHelper {
80 guint reply_forward_type;
81         ReplyForwardAction action;
82         gchar *account_name;
83 } ReplyForwardHelper;
84
85
86 static void     reply_forward_func     (gpointer data, gpointer user_data);
87 static void     read_msg_func          (gpointer data, gpointer user_data);
88 static void     get_msg_cb             (TnyFolder *folder, TnyMsg *msg, GError **err, 
89                                         gpointer user_data);
90 static void     reply_forward          (ReplyForwardAction action, ModestWindow *win);
91
92 static gchar*   ask_for_folder_name    (GtkWindow *parent_window, const gchar *title);
93
94
95 void   
96 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
97 {
98         GtkWidget *about;
99         const gchar *authors[] = {
100                 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
101                 NULL
102         };
103         about = gtk_about_dialog_new ();
104         gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
105         gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
106         gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
107                                         _("Copyright (c) 2006, Nokia Corporation\n"
108                                           "All rights reserved."));
109         gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
110                                        _("a modest e-mail client\n\n"
111                                          "design and implementation: Dirk-Jan C. Binnema\n"
112                                          "contributions from the fine people at KC and Ig\n"
113                                          "uses the tinymail email framework written by Philip van Hoof"));
114         gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
115         gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
116         
117         gtk_dialog_run (GTK_DIALOG (about));
118         gtk_widget_destroy(about);
119 }
120
121
122 static TnyList *
123 get_selected_headers (ModestWindow *win)
124 {
125         if (MODEST_IS_MAIN_WINDOW(win)) {
126                 GtkWidget *header_view;         
127                 
128                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
129                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
130                 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
131                 
132         } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
133                 /* for MsgViewWindows, we simply return a list with one element */
134                 TnyMsg *msg;
135                 TnyHeader *header;
136                 TnyList *list = NULL;
137                 
138                 msg  = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
139                 if (msg) {
140                         header = tny_msg_get_header (msg);
141                         list = tny_simple_list_new ();
142                         tny_list_prepend (list, G_OBJECT(header));
143                         g_object_unref (G_OBJECT(header));
144                 }
145                 return list;
146
147         } else
148                 return NULL;
149 }
150
151 void
152 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
153 {
154         TnyList *header_list;
155         TnyIterator *iter;
156
157         g_return_if_fail (MODEST_IS_WINDOW(win));
158                 
159         header_list = get_selected_headers (win);
160         
161         if (header_list) {
162                 iter = tny_list_create_iterator (header_list);
163                 do {
164                         TnyHeader *header;
165                         ModestMailOperation *mail_op;
166
167                         header = TNY_HEADER (tny_iterator_get_current (iter));
168                         /* TODO: thick grain mail operation involving
169                            a list of objects. Composite pattern ??? */
170                         /* TODO: add confirmation dialog */
171                         mail_op = modest_mail_operation_new ();
172                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
173                                                          mail_op);
174
175                         /* Always delete. TODO: Move to trash still not supported */
176                         modest_mail_operation_remove_msg (mail_op, header, FALSE);
177
178                         /* Frees */
179                         g_object_unref (G_OBJECT (mail_op));
180                         g_object_unref (G_OBJECT (header));
181
182                         tny_iterator_next (iter);
183
184                 } while (!tny_iterator_is_done (iter));
185
186                 /* Free iter */
187                 g_object_unref (G_OBJECT (iter));
188         }
189
190         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
191                 gtk_widget_destroy (GTK_WIDGET(win));
192         } 
193 }
194
195
196 void
197 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
198 {
199         gtk_main_quit ();
200 }
201
202 void
203 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
204 {
205         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
206                 gtk_widget_destroy (GTK_WIDGET (win));
207         } else if (MODEST_IS_WINDOW (win)) {
208                 gtk_widget_destroy (GTK_WIDGET (win));
209         } else {
210                 g_return_if_reached ();
211         }
212 }
213
214 void
215 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
216 {
217         GtkClipboard *clipboard = NULL;
218         gchar *selection = NULL;
219
220         clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
221         selection = gtk_clipboard_wait_for_text (clipboard);
222
223         modest_address_book_add_address (selection);
224         g_free (selection);
225 }
226
227 void
228 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
229 {
230         
231         /* This is currently only implemented for Maemo,
232          * because it requires a providers preset file which is not publically available.
233          */
234 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
235         GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr());
236         gboolean accounts_exist = account_names != NULL;
237         g_slist_free (account_names);
238         
239 /* To test, while modest_account_mgr_account_names() is broken: accounts_exist = TRUE; */
240         if (!accounts_exist) {
241                 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
242                 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
243                 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
244                 gtk_dialog_run (GTK_DIALOG (wizard));
245                 gtk_widget_destroy (GTK_WIDGET (wizard));
246         } else  {
247                 /* Show the list of accounts: */
248                 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
249                 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
250                 gtk_dialog_run (account_win);
251                 gtk_widget_destroy (GTK_WIDGET(account_win));
252         }
253 #else
254         GtkWidget *dialog, *label;
255         
256         /* Create the widgets */
257         
258         dialog = gtk_dialog_new_with_buttons ("Message",
259                                               GTK_WINDOW(win),
260                                               GTK_DIALOG_DESTROY_WITH_PARENT,
261                                               GTK_STOCK_OK,
262                                               GTK_RESPONSE_NONE,
263                                               NULL);
264         label = gtk_label_new ("Hello World!");
265         
266         /* Ensure that the dialog box is destroyed when the user responds. */
267         
268         g_signal_connect_swapped (dialog, "response", 
269                                   G_CALLBACK (gtk_widget_destroy),
270                                   dialog);
271         
272         /* Add the label, and show everything we've added to the dialog. */
273         
274         gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
275                            label);
276         gtk_widget_show_all (dialog);
277 #endif /* MODEST_PLATFORM_MAEMO */
278 }
279
280 void
281 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
282 {
283         ModestWindow *msg_win;
284         TnyMsg *msg = NULL;
285         TnyFolder *folder = NULL;
286         gchar *account_name = NULL;
287         gchar *from_str = NULL;
288         GError *err = NULL;
289         TnyAccount *account = NULL;
290         ModestWindowMgr *mgr;
291         
292         account_name = g_strdup(modest_window_get_active_account (win));
293         if (!account_name)
294                 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
295         if (!account_name) {
296                 g_printerr ("modest: no account found\n");
297                 goto cleanup;
298         }
299         
300         account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
301                                                                        account_name,
302                                                                        TNY_ACCOUNT_TYPE_STORE);
303         if (!account) {
304                 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
305                 goto cleanup;
306         }
307
308         from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
309         if (!from_str) {
310                 g_printerr ("modest: failed get from string for '%s'\n", account_name);
311                 goto cleanup;
312         }
313
314         msg = modest_tny_msg_new ("", from_str, "", "", "", "", NULL);
315         if (!msg) {
316                 g_printerr ("modest: failed to create new msg\n");
317                 goto cleanup;
318         }
319         
320         folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
321         if (!folder) {
322                 g_printerr ("modest: failed to find Drafts folder\n");
323                 goto cleanup;
324         }
325         
326         tny_folder_add_msg (folder, msg, &err);
327         if (err) {
328                 g_printerr ("modest: error adding msg to Drafts folder: %s",
329                             err->message);
330                 g_error_free (err);
331                 goto cleanup;
332         }
333
334         /* Create and register edit window */
335         msg_win = modest_msg_edit_window_new (msg, account_name);
336         mgr = modest_runtime_get_window_mgr ();
337         modest_window_mgr_register_window (mgr, msg_win);
338
339         if (win)
340                 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
341                                               GTK_WINDOW (win));        
342         gtk_widget_show_all (GTK_WIDGET (msg_win));
343
344 cleanup:
345         g_free (account_name);
346         g_free (from_str);
347         if (account)
348                 g_object_unref (G_OBJECT(account));
349         if (msg)
350                 g_object_unref (G_OBJECT(msg));
351         if (folder)
352                 g_object_unref (G_OBJECT(folder));
353 }
354
355
356 void
357 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
358 {
359         modest_runtime_not_implemented (GTK_WINDOW(win)); /* FIXME */
360 }
361
362
363
364 static void
365 reply_forward_func (gpointer data, gpointer user_data)
366 {
367         TnyMsg *msg, *new_msg;
368         GetMsgAsyncHelper *helper;
369         ReplyForwardHelper *rf_helper;
370         ModestWindow *msg_win;
371         ModestEditType edit_type;
372         gchar *from;
373         GError *err = NULL;
374         TnyFolder *folder = NULL;
375         TnyAccount *account = NULL;
376         ModestWindowMgr *mgr;
377         
378         msg = TNY_MSG (data);
379         helper = (GetMsgAsyncHelper *) user_data;
380         rf_helper = (ReplyForwardHelper *) helper->user_data;
381
382         from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
383                                                    rf_helper->account_name);
384         /* Create reply mail */
385         switch (rf_helper->action) {
386         case ACTION_REPLY:
387                 new_msg = 
388                         modest_tny_msg_create_reply_msg (msg,  from, 
389                                                          rf_helper->reply_forward_type,
390                                                          MODEST_TNY_MSG_REPLY_MODE_SENDER);
391                 break;
392         case ACTION_REPLY_TO_ALL:
393                 new_msg = 
394                         modest_tny_msg_create_reply_msg (msg, from, rf_helper->reply_forward_type,
395                                                          MODEST_TNY_MSG_REPLY_MODE_ALL);
396                 edit_type = MODEST_EDIT_TYPE_REPLY;
397                 break;
398         case ACTION_FORWARD:
399                 new_msg = 
400                         modest_tny_msg_create_forward_msg (msg, from, rf_helper->reply_forward_type);
401                 edit_type = MODEST_EDIT_TYPE_FORWARD;
402                 break;
403         default:
404                 g_return_if_reached ();
405                 return;
406         }
407
408         if (!new_msg) {
409                 g_printerr ("modest: failed to create message\n");
410                 goto cleanup;
411         }
412
413         account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
414                                                                        rf_helper->account_name,
415                                                                        TNY_ACCOUNT_TYPE_STORE);
416         if (!account) {
417                 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
418                 goto cleanup;
419         }
420
421         folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
422         if (!folder) {
423                 g_printerr ("modest: failed to find Drafts folder\n");
424                 goto cleanup;
425         }
426         
427         tny_folder_add_msg (folder, msg, &err);
428         if (err) {
429                 g_printerr ("modest: error adding msg to Drafts folder: %s",
430                             err->message);
431                 g_error_free (err);
432                 goto cleanup;
433         }       
434
435         /* Create and register the windows */                   
436         msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
437         mgr = modest_runtime_get_window_mgr ();
438         modest_window_mgr_register_window (mgr, msg_win);
439
440         /* Show edit window */
441         gtk_widget_show_all (GTK_WIDGET (msg_win));
442
443 cleanup:
444         if (new_msg)
445                 g_object_unref (G_OBJECT (new_msg));
446         if (folder)
447                 g_object_unref (G_OBJECT (folder));
448         if (account)
449                 g_object_unref (G_OBJECT (account));
450         
451         g_free (rf_helper->account_name);
452         g_slice_free (ReplyForwardHelper, rf_helper);
453 }
454 /*
455  * Common code for the reply and forward actions
456  */
457 static void
458 reply_forward (ReplyForwardAction action, ModestWindow *win)
459 {
460         TnyList *header_list;
461         guint reply_forward_type;
462         TnyHeader *header;
463         TnyFolder *folder;
464         GetMsgAsyncHelper *helper;
465         ReplyForwardHelper *rf_helper;
466         
467         g_return_if_fail (MODEST_IS_WINDOW(win));
468
469         header_list = get_selected_headers (win);
470         if (!header_list)
471                 return;
472         
473         reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (),
474                                                   (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
475                                                   NULL);
476         /* We assume that we can only select messages of the
477            same folder and that we reply all of them from the
478            same account. In fact the interface currently only
479            allows single selection */
480         
481         /* Fill helpers */
482         rf_helper = g_slice_new0 (ReplyForwardHelper);
483         rf_helper->reply_forward_type = reply_forward_type;
484         rf_helper->action = action;
485
486         rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
487         if (!rf_helper->account_name)
488                 rf_helper->account_name =
489                         modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
490
491         helper = g_slice_new0 (GetMsgAsyncHelper);
492         helper->window = win;
493         helper->func = reply_forward_func;
494         helper->iter = tny_list_create_iterator (header_list);
495         helper->user_data = rf_helper;
496
497         if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
498                 TnyMsg *msg;
499                 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
500                 if (!msg) {
501                         g_printerr ("modest: no message found\n");
502                         return;
503                 } else
504                         reply_forward_func (msg, helper);
505         } else {
506                 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
507                 folder = tny_header_get_folder (header);
508                 if (folder) {
509                         /* The callback will call it per each header */
510                         tny_folder_get_msg_async (folder, header, get_msg_cb, NULL, helper);
511                         g_object_unref (G_OBJECT (folder));
512                 } else 
513                         g_printerr ("modest: no folder for header\n");
514                 
515                 /* Clean */
516                 g_object_unref (G_OBJECT (header));
517         }
518 }
519
520
521 void
522 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
523 {
524         g_return_if_fail (MODEST_IS_WINDOW(win));
525
526         reply_forward (ACTION_REPLY, win);
527 }
528
529 void
530 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
531 {
532         g_return_if_fail (MODEST_IS_WINDOW(win));
533
534         reply_forward (ACTION_FORWARD, win);
535 }
536
537 void
538 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
539 {
540         g_return_if_fail (MODEST_IS_WINDOW(win));
541
542         reply_forward (ACTION_REPLY_TO_ALL, win);
543 }
544
545 void 
546 modest_ui_actions_on_next (GtkAction *action, 
547                            ModestWindow *window)
548 {
549         if (MODEST_IS_MAIN_WINDOW (window)) {
550                 GtkWidget *header_view;
551
552                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
553                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
554                 if (!header_view)
555                         return;
556         
557                 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view)); 
558         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
559                 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
560         } else {
561                 g_return_if_reached ();
562         }
563 }
564
565 void 
566 modest_ui_actions_on_prev (GtkAction *action, 
567                            ModestWindow *window)
568 {
569         g_return_if_fail (MODEST_IS_WINDOW(window));
570
571         if (MODEST_IS_MAIN_WINDOW (window)) {
572                 GtkWidget *header_view;
573                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
574                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
575                 if (!header_view)
576                         return;
577                 
578                 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view)); 
579         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
580                 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
581         } else {
582                 g_return_if_reached ();
583         }
584 }
585
586 void 
587 modest_ui_actions_on_sort (GtkAction *action, 
588                            ModestWindow *window)
589 {
590         ModestWindowMgr *mgr;
591
592         g_return_if_fail (MODEST_IS_WINDOW(window));
593
594         /* Show sorting dialog */
595         mgr = modest_runtime_get_window_mgr ();
596         
597 }
598
599
600 static gboolean
601 action_send (const gchar* account_name)
602 {
603         TnyAccount *tny_account;
604         ModestTnySendQueue *send_queue;
605
606         g_return_val_if_fail (account_name, FALSE);
607
608         tny_account = 
609                 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
610                                                                      account_name,
611                                                                      TNY_ACCOUNT_TYPE_TRANSPORT);
612         if (!tny_account) {
613                 g_printerr ("modest: cannot get tny transport account for %s\n", account_name);
614                 return FALSE;
615         }
616         send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(tny_account));
617         if (!send_queue) {
618                 g_object_unref (G_OBJECT(tny_account));
619                 g_printerr ("modest: cannot get send queue for %s\n", account_name);
620                 return FALSE;
621         }
622         
623         //modest_tny_send_queue_flush (send_queue);
624
625         g_object_unref (G_OBJECT(send_queue));
626         g_object_unref (G_OBJECT(tny_account));
627
628         return TRUE;
629 }
630
631
632 static gboolean
633 action_receive (const gchar* account_name)
634 {
635         TnyAccount *tny_account;
636         ModestMailOperation *mail_op;
637
638         g_return_val_if_fail (account_name, FALSE);
639
640         tny_account = 
641                 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
642                                                                      account_name,
643                                                                      TNY_ACCOUNT_TYPE_STORE);
644         if (!tny_account) {
645                 g_printerr ("modest: cannot get tny store account for %s\n", account_name);
646                 return FALSE;
647         }
648
649         /* Create the mail operation */
650         mail_op = modest_mail_operation_new ();
651         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
652         modest_mail_operation_update_account (mail_op, TNY_STORE_ACCOUNT(tny_account));
653
654         g_object_unref (G_OBJECT(tny_account));
655         g_object_unref (G_OBJECT (mail_op));
656                 
657         return TRUE;
658 }
659
660
661
662 void
663 modest_ui_actions_on_send_receive (GtkAction *action,  ModestWindow *win)
664 {
665         gchar *account_name;
666
667         
668         g_message ("online? %s", 
669                 tny_device_is_online(modest_runtime_get_device()) ? "yes":"no");
670                                                                 
671         account_name =
672                 g_strdup(modest_window_get_active_account(MODEST_WINDOW(win)));
673         if (!account_name)
674                 account_name  = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
675         if (!account_name) {
676                 g_printerr ("modest: cannot get account\n");
677                 return;
678         }
679
680         if (!action_send(account_name))
681                 g_printerr ("modest: failed to send\n");
682         if (!action_receive(account_name))
683                 g_printerr ("modest: failed to receive\n");
684 }
685
686
687
688 void
689 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
690 {
691         ModestConf *conf;
692         GtkWidget *header_view;
693         
694         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
695
696         header_view = modest_main_window_get_child_widget (main_window,
697                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
698         if (!header_view)
699                 return;
700
701         conf = modest_runtime_get_conf ();
702         
703         /* what is saved/restored is depending on the style; thus; we save with
704          * old style, then update the style, and restore for this new style
705          */
706         modest_widget_memory_save (conf, G_OBJECT(header_view), "header-view");
707         
708         if (modest_header_view_get_style
709             (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
710                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
711                                               MODEST_HEADER_VIEW_STYLE_TWOLINES);
712         else
713                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
714                                               MODEST_HEADER_VIEW_STYLE_DETAILS);
715
716         modest_widget_memory_restore (conf, G_OBJECT(header_view),
717                                       "header-view");
718 }
719
720
721
722 /*
723  * Marks a message as read and passes it to the msg preview widget
724  */
725 static void
726 read_msg_func (gpointer data, gpointer user_data)
727 {
728         TnyMsg *msg;
729         TnyHeader *header;
730         GetMsgAsyncHelper *helper;
731         TnyHeaderFlags header_flags;
732         GtkWidget *msg_preview;
733         
734         msg = TNY_MSG (data);
735         helper = (GetMsgAsyncHelper *) user_data;
736
737         msg_preview = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (helper->window),
738                                                            MODEST_WIDGET_TYPE_MSG_PREVIEW);
739         if (!msg_preview)
740                 return;
741         
742         header = TNY_HEADER (tny_iterator_get_current (helper->iter));
743         header_flags = tny_header_get_flags (header);
744         tny_header_set_flags (header, header_flags | TNY_HEADER_FLAG_SEEN);
745         g_object_unref (G_OBJECT (header));
746
747         /* Set message on msg view */
748         modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), msg);
749 }
750
751 /*
752  * This function is a generic handler for the tny_folder_get_msg_async
753  * call. It expects as user_data a #GetMsgAsyncHelper. This helper
754  * contains a user provided function that is called inside this
755  * method. This will allow us to use this callback in many different
756  * places. This callback performs the common actions for the
757  * get_msg_async call, more specific actions will be done by the user
758  * function
759  */
760 static void
761 get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data)
762 {
763         GetMsgAsyncHelper *helper;
764
765         helper = (GetMsgAsyncHelper *) user_data;
766
767         if ((*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) || !msg) {
768                 modest_ui_actions_on_item_not_found (NULL,
769                                                      MODEST_ITEM_TYPE_MESSAGE,
770                                                      helper->window);
771                 return;
772         }
773
774         /* Call user function */
775         helper->func (msg, user_data);
776
777         /* Process next element (if exists) */
778         tny_iterator_next (helper->iter);
779         if (tny_iterator_is_done (helper->iter)) {
780                 TnyList *headers;
781                 headers = tny_iterator_get_list (helper->iter);
782                 /* Free resources */
783                 g_object_unref (G_OBJECT (headers));
784                 g_object_unref (G_OBJECT (helper->iter));
785                 g_slice_free (GetMsgAsyncHelper, helper);
786         } else {
787                 TnyHeader *header;
788                 header = TNY_HEADER (tny_iterator_get_current (helper->iter)); 
789                 tny_folder_get_msg_async (folder, header,                         
790                                           get_msg_cb, NULL, helper);
791                 g_object_unref (G_OBJECT(header));
792         }
793 }
794
795 void 
796 modest_ui_actions_on_header_selected (ModestHeaderView *header_view, 
797                                       TnyHeader *header,
798                                       ModestMainWindow *main_window)
799 {
800         TnyFolder *folder;
801         GetMsgAsyncHelper *helper;
802         TnyList *list;
803
804         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
805
806         /* when there's no header, clear the msgview */
807         if (!header) {
808                 GtkWidget *msg_preview;
809
810                 /* Clear msg preview if exists */
811                 msg_preview = modest_main_window_get_child_widget(main_window,
812                                                                   MODEST_WIDGET_TYPE_MSG_PREVIEW);
813         
814                 if (msg_preview)
815                         modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), NULL);
816                 return;
817         }
818
819         /* Update Main window title */
820         if (GTK_WIDGET_HAS_FOCUS (header_view)) {
821                 const gchar *subject = tny_header_get_subject (header);
822                 if (subject && strcmp (subject, ""))
823                         gtk_window_set_title (GTK_WINDOW (main_window), subject);
824                 else
825                         gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
826         }
827
828         /* Create list */
829         list = tny_simple_list_new ();
830         tny_list_prepend (list, G_OBJECT (header));
831
832         /* Fill helper data */
833         helper = g_slice_new0 (GetMsgAsyncHelper);
834         helper->window = MODEST_WINDOW (main_window);
835         helper->iter = tny_list_create_iterator (list);
836         helper->func = read_msg_func;
837
838         folder = tny_header_get_folder (TNY_HEADER(header));
839
840         tny_folder_get_msg_async (TNY_FOLDER(folder),
841                                   header, get_msg_cb,
842                                   NULL, helper);
843
844         /* Frees */
845         g_object_unref (G_OBJECT (folder));
846 }
847
848
849
850 void 
851 modest_ui_actions_on_header_activated (ModestHeaderView *folder_view, TnyHeader *header,
852                                        ModestMainWindow *main_window)
853 {
854         ModestWindow *win = NULL;
855         TnyFolder *folder = NULL;
856         TnyMsg    *msg    = NULL;
857         ModestWindowMgr *mgr;
858         
859         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
860         
861         if (!header)
862                 return;
863
864         folder = tny_header_get_folder (header);
865         if (!folder) {
866                 g_printerr ("modest: cannot get folder for header\n");
867                 return;
868         }
869
870         /* FIXME: make async?; check error  */
871         msg = tny_folder_get_msg (folder, header, NULL);
872         if (!msg) {
873                 g_printerr ("modest: cannot get msg for header\n");
874                 goto cleanup;
875         }
876
877         /* Look if we already have a message view for that header */    
878         mgr = modest_runtime_get_window_mgr ();
879         win = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
880
881         /* If not, create a new window */
882         if (!win) {
883                 gchar *account;
884
885                 account =  g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window)));
886                 if (!account)
887                         account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
888
889                 win = modest_msg_view_window_new (msg, account);
890                 modest_window_mgr_register_window (mgr, win);
891
892                 gtk_window_set_transient_for (GTK_WINDOW (win),
893                                               GTK_WINDOW (main_window));
894         }
895
896         gtk_widget_show_all (GTK_WIDGET(win));
897
898         g_object_unref (G_OBJECT (msg));
899         
900 cleanup:
901         g_object_unref (G_OBJECT (folder));
902 }
903
904 void 
905 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
906                                                TnyFolderStore *folder_store, 
907                                                gboolean selected,
908                                                ModestMainWindow *main_window)
909 {
910         ModestConf *conf;
911         GtkWidget *header_view;
912         
913         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
914
915         header_view = modest_main_window_get_child_widget(main_window,
916                                                           MODEST_WIDGET_TYPE_HEADER_VIEW);
917         if (!header_view)
918                 return;
919         
920         conf = modest_runtime_get_conf ();
921
922         if (TNY_IS_FOLDER (folder_store)) {
923
924                 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
925
926                 if (selected) {
927                         modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), 
928                                                        TNY_FOLDER (folder_store));
929                         modest_widget_memory_restore (conf, G_OBJECT(header_view),
930                                                       "header-view");
931                 } else {
932                         modest_widget_memory_save (conf, G_OBJECT (header_view), "header-view");
933                         modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
934                 }
935         } else if (TNY_IS_ACCOUNT (folder_store)) {
936
937                 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
938         }
939 }
940
941 void 
942 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
943                                      ModestWindow *win)
944 {
945         GtkWidget *dialog;
946         gchar *txt, *item;
947         gboolean online;
948
949         item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
950         
951         if (g_main_depth > 0)   
952                 gdk_threads_enter ();
953         online = tny_device_is_online (modest_runtime_get_device());
954
955         if (online) {
956                 /* already online -- the item is simply not there... */
957                 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
958                                                  GTK_DIALOG_MODAL,
959                                                  GTK_MESSAGE_WARNING,
960                                                  GTK_BUTTONS_OK,
961                                                  _("The %s you selected cannot be found"),
962                                                  item);
963                 gtk_dialog_run (GTK_DIALOG(dialog));
964         } else {
965                 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
966                                                       GTK_WINDOW (win),
967                                                       GTK_DIALOG_MODAL,
968                                                       GTK_STOCK_CANCEL,
969                                                       GTK_RESPONSE_REJECT,
970                                                       GTK_STOCK_OK,
971                                                       GTK_RESPONSE_ACCEPT,
972                                                       NULL);
973                 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
974                                          "Do you want to get online?"), item);
975                 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
976                                     gtk_label_new (txt), FALSE, FALSE, 0);
977                 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
978                 g_free (txt);
979
980                 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
981                 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
982 //                      tny_device_force_online (modest_runtime_get_device());
983                 }
984         }
985         gtk_widget_destroy (dialog);
986         if (g_main_depth > 0)   
987                 gdk_threads_leave ();
988 }
989
990 void
991 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
992                                      ModestWindow *win)
993 {
994         g_message ("%s %s", __FUNCTION__, link);
995 }       
996
997
998 void
999 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1000                                         ModestWindow *win)
1001 {
1002         modest_platform_activate_uri (link);
1003 }
1004
1005 void
1006 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1007                                           ModestWindow *win)
1008 {
1009         modest_platform_show_uri_popup (link);
1010 }
1011
1012 void
1013 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1014                                              ModestWindow *win)
1015 {
1016         g_message (__FUNCTION__);
1017         
1018 }
1019
1020 void
1021 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1022                                           const gchar *address,
1023                                           ModestWindow *win)
1024 {
1025         g_message ("%s %s", __FUNCTION__, address);
1026 }
1027
1028 void
1029 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1030 {
1031         TnyTransportAccount *transport_account;
1032         ModestMailOperation *mail_operation;
1033         MsgData *data;
1034         gchar *account_name, *from;
1035         ModestAccountMgr *account_mgr;
1036
1037         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1038         
1039         data = modest_msg_edit_window_get_msg_data (edit_window);
1040
1041         /* FIXME: Code added just for testing. The final version will
1042            use the send queue provided by tinymail and some
1043            classifier */
1044         account_mgr = modest_runtime_get_account_mgr();
1045         account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1046         if (!account_name) 
1047                 account_name = modest_account_mgr_get_default_account (account_mgr);
1048         if (!account_name) {
1049                 g_printerr ("modest: no account found\n");
1050                 modest_msg_edit_window_free_msg_data (edit_window, data);
1051                 return;
1052         }
1053         transport_account =
1054                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1055                                       (modest_runtime_get_account_store(),
1056                                        account_name,
1057                                        TNY_ACCOUNT_TYPE_TRANSPORT));
1058         if (!transport_account) {
1059                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1060                 g_free (account_name);
1061                 modest_msg_edit_window_free_msg_data (edit_window, data);
1062                 return;
1063         }
1064         from = modest_account_mgr_get_from_string (account_mgr, account_name);
1065
1066         /* Create the mail operation */         
1067         mail_operation = modest_mail_operation_new ();
1068         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1069
1070         modest_mail_operation_send_new_mail (mail_operation,
1071                                              transport_account,
1072                                              from,
1073                                              data->to, 
1074                                              data->cc, 
1075                                              data->bcc,
1076                                              data->subject, 
1077                                              data->plain_body, 
1078                                              data->html_body,
1079                                              data->attachments,
1080                                              data->priority_flags);
1081         /* Frees */
1082         g_free (from);
1083         g_free (account_name);
1084         g_object_unref (G_OBJECT (transport_account));
1085         g_object_unref (G_OBJECT (mail_operation));
1086
1087         modest_msg_edit_window_free_msg_data (edit_window, data);
1088
1089         /* Save settings and close the window */
1090         gtk_widget_destroy (GTK_WIDGET (edit_window));
1091 }
1092
1093 void 
1094 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1095                                   ModestMsgEditWindow *window)
1096 {
1097         ModestMsgEditFormatState *format_state = NULL;
1098
1099         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1100         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1101
1102         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1103                 return;
1104
1105         format_state = modest_msg_edit_window_get_format_state (window);
1106         g_return_if_fail (format_state != NULL);
1107
1108         format_state->bold = gtk_toggle_action_get_active (action);
1109         modest_msg_edit_window_set_format_state (window, format_state);
1110         g_free (format_state);
1111         
1112 }
1113
1114 void 
1115 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1116                                      ModestMsgEditWindow *window)
1117 {
1118         ModestMsgEditFormatState *format_state = NULL;
1119
1120         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1121         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1122
1123         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1124                 return;
1125
1126         format_state = modest_msg_edit_window_get_format_state (window);
1127         g_return_if_fail (format_state != NULL);
1128
1129         format_state->italics = gtk_toggle_action_get_active (action);
1130         modest_msg_edit_window_set_format_state (window, format_state);
1131         g_free (format_state);
1132         
1133 }
1134
1135 void 
1136 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1137                                      ModestMsgEditWindow *window)
1138 {
1139         ModestMsgEditFormatState *format_state = NULL;
1140
1141         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1142         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1143
1144         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1145                 return;
1146
1147         format_state = modest_msg_edit_window_get_format_state (window);
1148         g_return_if_fail (format_state != NULL);
1149
1150         format_state->bullet = gtk_toggle_action_get_active (action);
1151         modest_msg_edit_window_set_format_state (window, format_state);
1152         g_free (format_state);
1153         
1154 }
1155
1156 void 
1157 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1158                                      GtkRadioAction *selected,
1159                                      ModestMsgEditWindow *window)
1160 {
1161         ModestMsgEditFormatState *format_state = NULL;
1162         GtkJustification value;
1163
1164         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1165
1166         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1167                 return;
1168
1169         value = gtk_radio_action_get_current_value (selected);
1170
1171         format_state = modest_msg_edit_window_get_format_state (window);
1172         g_return_if_fail (format_state != NULL);
1173
1174         format_state->justification = value;
1175         modest_msg_edit_window_set_format_state (window, format_state);
1176         g_free (format_state);
1177 }
1178
1179 void 
1180 modest_ui_actions_on_select_editor_color (GtkAction *action,
1181                                           ModestMsgEditWindow *window)
1182 {
1183         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1184         g_return_if_fail (GTK_IS_ACTION (action));
1185
1186         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1187                 return;
1188
1189         modest_msg_edit_window_select_color (window);
1190 }
1191
1192 void 
1193 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1194                                                      ModestMsgEditWindow *window)
1195 {
1196         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1197         g_return_if_fail (GTK_IS_ACTION (action));
1198
1199         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1200                 return;
1201
1202         modest_msg_edit_window_select_background_color (window);
1203 }
1204
1205 void 
1206 modest_ui_actions_on_insert_image (GtkAction *action,
1207                                    ModestMsgEditWindow *window)
1208 {
1209         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1210         g_return_if_fail (GTK_IS_ACTION (action));
1211
1212         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1213                 return;
1214
1215         modest_msg_edit_window_insert_image (window);
1216 }
1217
1218 /*
1219  * Shows a dialog with an entry that asks for some text. The returned
1220  * value must be freed by the caller. The dialog window title will be
1221  * set to @title.
1222  */
1223 static gchar *
1224 ask_for_folder_name (GtkWindow *parent_window,
1225                      const gchar *title)
1226 {
1227         GtkWidget *dialog, *entry;
1228         gchar *folder_name = NULL;
1229
1230         /* Ask for folder name */
1231         dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1232                                               parent_window,
1233                                               GTK_DIALOG_MODAL,
1234                                               GTK_STOCK_CANCEL,
1235                                               GTK_RESPONSE_REJECT,
1236                                               GTK_STOCK_OK,
1237                                               GTK_RESPONSE_ACCEPT,
1238                                               NULL);
1239         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1240                             gtk_label_new(title),
1241                             FALSE, FALSE, 0);
1242                 
1243         entry = gtk_entry_new_with_max_length (40);
1244         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1245                             entry,
1246                             TRUE, FALSE, 0);    
1247         
1248         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1249         
1250         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)         
1251                 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1252
1253         gtk_widget_destroy (dialog);
1254
1255         return folder_name;
1256 }
1257
1258 void 
1259 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1260 {
1261         TnyFolderStore *parent_folder;
1262         GtkWidget *folder_view;
1263         
1264         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1265
1266         folder_view = modest_main_window_get_child_widget (main_window,
1267                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1268         if (!folder_view)
1269                 return;
1270
1271         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1272         
1273         if (parent_folder) {
1274                 gboolean finished = FALSE;
1275                 gint result;
1276                 gchar *folder_name = NULL, *suggested_name = NULL;
1277
1278                 /* Run the new folder dialog */
1279                 while (!finished) {
1280                         result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1281                                                                         parent_folder,
1282                                                                         suggested_name,
1283                                                                         &folder_name);
1284
1285                         if (result == GTK_RESPONSE_REJECT) {
1286                                 finished = TRUE;
1287                         } else {
1288                                 ModestMailOperation *mail_op = modest_mail_operation_new ();
1289                                 TnyFolder *new_folder = NULL;
1290
1291                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
1292                                                                  mail_op);
1293                 
1294                                 new_folder = modest_mail_operation_create_folder (mail_op,
1295                                                                                   parent_folder,
1296                                                                                   (const gchar *) folder_name);
1297                                 if (new_folder) {
1298                                         g_object_unref (new_folder);
1299                                         finished = TRUE;
1300                                 } 
1301 /*                              else { */
1302 /*                                      /\* TODO: check error and follow proper actions *\/ */
1303 /* /\*                                  suggested_name = X; *\/ */
1304 /*                                      /\* Show error to the user *\/ */
1305 /*                                      modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
1306 /*                                                                              MODEST_INFORMATION_CREATE_FOLDER); */
1307 /*                              } */
1308                                 g_object_unref (mail_op);
1309                         }
1310                         g_free (folder_name);
1311                         folder_name = NULL;
1312                 }
1313
1314                 g_object_unref (parent_folder);
1315         }
1316 }
1317
1318 void 
1319 modest_ui_actions_on_rename_folder (GtkAction *action,
1320                                      ModestMainWindow *main_window)
1321 {
1322         TnyFolderStore *folder;
1323         GtkWidget *folder_view;
1324         
1325         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1326
1327         folder_view = modest_main_window_get_child_widget (main_window,
1328                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1329         if (!folder_view)
1330                 return;
1331         
1332         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1333         
1334         if (folder && TNY_IS_FOLDER (folder)) {
1335                 gchar *folder_name;
1336                 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1337                                                    _("Please enter a new name for the folder"));
1338
1339                 if (folder_name != NULL && strlen (folder_name) > 0) {
1340                         ModestMailOperation *mail_op;
1341
1342                         mail_op = modest_mail_operation_new ();
1343                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1344                                                          mail_op);
1345
1346                         modest_mail_operation_rename_folder (mail_op,
1347                                                              TNY_FOLDER (folder),
1348                                                              (const gchar *) folder_name);
1349
1350                         g_object_unref (mail_op);
1351                         g_free (folder_name);
1352                 }
1353                 g_object_unref (folder);
1354         }
1355 }
1356
1357 static void
1358 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash) 
1359 {
1360         TnyFolderStore *folder;
1361         GtkWidget *folder_view;
1362         gint response;
1363         
1364         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1365
1366         folder_view = modest_main_window_get_child_widget (main_window,
1367                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1368         if (!folder_view)
1369                 return;
1370
1371         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1372
1373         /* Ask the user */      
1374         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window), 
1375                                                             MODEST_CONFIRMATION_DELETE_FOLDER,
1376                                                             folder);
1377
1378         if (response == GTK_RESPONSE_OK) {
1379                 ModestMailOperation *mail_op = modest_mail_operation_new ();
1380
1381                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1382                                                  mail_op);
1383                 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1384
1385                 /* Show error if happened */
1386                 if (modest_mail_operation_get_error (mail_op))
1387                         modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1388                                                                 MODEST_INFORMATION_DELETE_FOLDER);
1389
1390                 g_object_unref (G_OBJECT (mail_op));
1391         }
1392
1393         g_object_unref (G_OBJECT (folder));
1394 }
1395
1396 void 
1397 modest_ui_actions_on_delete_folder (GtkAction *action,
1398                                      ModestMainWindow *main_window)
1399 {
1400         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1401
1402         delete_folder (main_window, FALSE);
1403 }
1404
1405 void 
1406 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1407 {
1408         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1409         
1410         delete_folder (main_window, TRUE);
1411 }
1412
1413 void
1414 modest_ui_actions_on_password_requested (TnyAccountStore *account_store, 
1415                                          const gchar* account_name,
1416                                          gchar **password, 
1417                                          gboolean *cancel, 
1418                                          gboolean *remember,
1419                                          ModestMainWindow *main_window)
1420 {
1421         gchar *txt;
1422         GtkWidget *dialog, *entry, *remember_pass_check;
1423
1424         dialog = gtk_dialog_new_with_buttons (_("Password requested"),
1425                                               NULL,
1426                                               GTK_DIALOG_MODAL,
1427                                               GTK_STOCK_CANCEL,
1428                                               GTK_RESPONSE_REJECT,
1429                                               GTK_STOCK_OK,
1430                                               GTK_RESPONSE_ACCEPT,
1431                                               NULL);
1432         gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1433         
1434         txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
1435         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1436                             FALSE, FALSE, 0);
1437         g_free (txt);
1438
1439         entry = gtk_entry_new_with_max_length (40);
1440         gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
1441         gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
1442         
1443         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
1444                             TRUE, FALSE, 0);    
1445
1446         remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1447         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1448                             TRUE, FALSE, 0);
1449
1450         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1451         
1452         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1453                 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
1454                 *cancel   = FALSE;
1455         } else {
1456                 *password = NULL;
1457                 *cancel   = TRUE;
1458         }
1459
1460         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1461                 *remember = TRUE;
1462         else
1463                 *remember = FALSE;
1464
1465         gtk_widget_destroy (dialog);
1466 }
1467
1468 void
1469 modest_ui_actions_on_cut (GtkAction *action,
1470                           ModestWindow *window)
1471 {
1472         GtkWidget *focused_widget;
1473
1474         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1475         if (GTK_IS_EDITABLE (focused_widget)) {
1476                 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1477         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1478                 GtkTextBuffer *buffer;
1479                 GtkClipboard *clipboard;
1480
1481                 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1482                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1483                 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1484         }
1485 }
1486
1487 void
1488 modest_ui_actions_on_copy (GtkAction *action,
1489                            ModestWindow *window)
1490 {
1491         GtkClipboard *clipboard;
1492         GtkWidget *focused_widget;
1493
1494         clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1495         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1496         if (GTK_IS_LABEL (focused_widget)) {
1497                 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1498         } else if (GTK_IS_EDITABLE (focused_widget)) {
1499                 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1500         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1501                 GtkTextBuffer *buffer;
1502
1503                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1504                 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1505         }
1506 }
1507
1508 void
1509 modest_ui_actions_on_undo (GtkAction *action,
1510                            ModestWindow *window)
1511 {
1512         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
1513                 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
1514         } else {
1515                 g_return_if_reached ();
1516         }
1517 }
1518
1519 void
1520 modest_ui_actions_on_paste (GtkAction *action,
1521                             ModestWindow *window)
1522 {
1523         GtkWidget *focused_widget;
1524
1525         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1526         if (GTK_IS_EDITABLE (focused_widget)) {
1527                 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1528         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1529                 GtkTextBuffer *buffer;
1530                 GtkClipboard *clipboard;
1531
1532                 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1533                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1534                 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1535         }
1536 }
1537
1538 void
1539 modest_ui_actions_on_select_all (GtkAction *action,
1540                                  ModestWindow *window)
1541 {
1542         GtkWidget *focused_widget;
1543
1544         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1545         if (GTK_IS_LABEL (focused_widget)) {
1546                 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1547         } else if (GTK_IS_EDITABLE (focused_widget)) {
1548                 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1549         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1550                 GtkTextBuffer *buffer;
1551                 GtkTextIter start, end;
1552
1553                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1554                 gtk_text_buffer_get_start_iter (buffer, &start);
1555                 gtk_text_buffer_get_end_iter (buffer, &end);
1556                 gtk_text_buffer_select_range (buffer, &start, &end);
1557         }
1558 }
1559
1560 void
1561 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
1562                                   GtkRadioAction *selected,
1563                                   ModestWindow *window)
1564 {
1565         gint value;
1566
1567         value = gtk_radio_action_get_current_value (selected);
1568         if (MODEST_IS_WINDOW (window)) {
1569                 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
1570         }
1571 }
1572
1573 void     modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
1574                                                         GtkRadioAction *selected,
1575                                                         ModestWindow *window)
1576 {
1577         TnyHeaderFlags flags;
1578         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1579
1580         flags = gtk_radio_action_get_current_value (selected);
1581         modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
1582 }
1583
1584 void     modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
1585                                                            GtkRadioAction *selected,
1586                                                            ModestWindow *window)
1587 {
1588         gint file_format;
1589
1590         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1591
1592         file_format = gtk_radio_action_get_current_value (selected);
1593         modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
1594 }
1595
1596
1597 void     
1598 modest_ui_actions_on_zoom_plus (GtkAction *action,
1599                                 ModestWindow *window)
1600 {
1601         g_return_if_fail (MODEST_IS_WINDOW (window));
1602
1603         modest_window_zoom_plus (MODEST_WINDOW (window));
1604 }
1605
1606 void     
1607 modest_ui_actions_on_zoom_minus (GtkAction *action,
1608                                  ModestWindow *window)
1609 {
1610         g_return_if_fail (MODEST_IS_WINDOW (window));
1611
1612         modest_window_zoom_minus (MODEST_WINDOW (window));
1613 }
1614
1615 void     
1616 modest_ui_actions_on_toggle_fullscreen    (GtkToggleAction *toggle,
1617                                            ModestWindow *window)
1618 {
1619         ModestWindowMgr *mgr;
1620         gboolean fullscreen, active;
1621         g_return_if_fail (MODEST_IS_WINDOW (window));
1622
1623         mgr = modest_runtime_get_window_mgr ();
1624
1625         active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
1626         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1627
1628         if (active != fullscreen) {
1629                 modest_window_mgr_set_fullscreen_mode (mgr, active);
1630                 gtk_window_present (GTK_WINDOW (window));
1631         }
1632 }
1633
1634 void
1635 modest_ui_actions_on_change_fullscreen (GtkAction *action,
1636                                         ModestWindow *window)
1637 {
1638         ModestWindowMgr *mgr;
1639         gboolean fullscreen;
1640
1641         g_return_if_fail (MODEST_IS_WINDOW (window));
1642
1643         mgr = modest_runtime_get_window_mgr ();
1644         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1645         modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
1646
1647         gtk_window_present (GTK_WINDOW (window));
1648 }
1649
1650 /*
1651  * Show the header details in a ModestDetailsDialog widget
1652  */
1653 static void
1654 show_header_details (TnyHeader *header, 
1655                      GtkWindow *window)
1656 {
1657         GtkWidget *dialog;
1658         
1659         /* Create dialog */
1660         dialog = modest_details_dialog_new_with_header (window, header);
1661
1662         /* Run dialog */
1663         gtk_widget_show_all (dialog);
1664         gtk_dialog_run (GTK_DIALOG (dialog));
1665
1666         gtk_widget_destroy (dialog);
1667 }
1668
1669 /*
1670  * Show the folder details in a ModestDetailsDialog widget
1671  */
1672 static void
1673 show_folder_details (TnyFolder *folder, 
1674                      GtkWindow *window)
1675 {
1676         GtkWidget *dialog;
1677         
1678         /* Create dialog */
1679         dialog = modest_details_dialog_new_with_folder (window, folder);
1680
1681         /* Run dialog */
1682         gtk_widget_show_all (dialog);
1683         gtk_dialog_run (GTK_DIALOG (dialog));
1684
1685         gtk_widget_destroy (dialog);
1686 }
1687
1688
1689 void     
1690 modest_ui_actions_on_details (GtkAction *action, 
1691                               ModestWindow *win)
1692 {
1693         TnyList * headers_list;
1694         TnyIterator *iter;
1695         TnyHeader *header;              
1696
1697         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1698                 TnyMsg *msg;
1699
1700                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
1701                 if (!msg) {
1702                         return;
1703                 } else {
1704                         headers_list = get_selected_headers (win);
1705                         if (!headers_list)
1706                                 return;
1707
1708                         iter = tny_list_create_iterator (headers_list);
1709
1710                         header = TNY_HEADER (tny_iterator_get_current (iter));
1711                         show_header_details (header, GTK_WINDOW (win));
1712                         g_object_unref (header);
1713
1714                         g_object_unref (iter);
1715                 }
1716         } else if (MODEST_IS_MAIN_WINDOW (win)) {
1717                 GtkWidget *folder_view, *header_view;
1718
1719                 /* Check which widget has the focus */
1720                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1721                                                                     MODEST_WIDGET_TYPE_FOLDER_VIEW);
1722                 if (gtk_widget_is_focus (folder_view)) {
1723                         TnyFolder *folder;
1724
1725                         folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1726
1727                         /* Show only when it's a folder */
1728                         if (!folder || !TNY_IS_FOLDER (folder))
1729                                 return;
1730
1731                         show_folder_details (folder, GTK_WINDOW (win));
1732
1733                 } else {
1734                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1735                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
1736                         if (!gtk_widget_is_focus (header_view))
1737                                 return;
1738
1739                         headers_list = get_selected_headers (win);
1740                         if (!headers_list)
1741                                 return;
1742
1743                         iter = tny_list_create_iterator (headers_list);
1744                         while (!tny_iterator_is_done (iter)) {
1745
1746                                 header = TNY_HEADER (tny_iterator_get_current (iter));
1747                                 show_header_details (header, GTK_WINDOW (win));
1748                                 g_object_unref (header);
1749
1750                                 tny_iterator_next (iter);
1751                         }
1752                         g_object_unref (iter);
1753                 }
1754         }
1755 }
1756
1757 void     
1758 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
1759                                      ModestMsgEditWindow *window)
1760 {
1761         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1762
1763         modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
1764 }
1765
1766 void     
1767 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
1768                                       ModestMsgEditWindow *window)
1769 {
1770         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1771
1772         modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
1773 }
1774
1775 void
1776 modest_ui_actions_toggle_folders_view (GtkAction *action, 
1777                                        ModestMainWindow *main_window)
1778 {
1779         ModestConf *conf;
1780         
1781         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1782
1783         conf = modest_runtime_get_conf ();
1784         
1785         if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
1786                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
1787         else
1788                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
1789 }
1790
1791 void 
1792 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle, 
1793                                      ModestWindow *window)
1794 {
1795         gboolean active, fullscreen = FALSE;
1796         ModestWindowMgr *mgr;
1797
1798         active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
1799
1800         /* Check if we want to toggle the toolbar vuew in fullscreen
1801            or normal mode */
1802         if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)), 
1803                      "ViewShowToolbarFullScreen")) {
1804                 fullscreen = TRUE;
1805         }
1806
1807         /* Toggle toolbar */
1808         mgr = modest_runtime_get_window_mgr ();
1809         modest_window_mgr_show_toolbars (mgr, active, fullscreen);
1810 }
1811
1812 void     
1813 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
1814                                            ModestMsgEditWindow *window)
1815 {
1816         modest_msg_edit_window_select_font (window);
1817 }
1818
1819 void
1820 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
1821                                                   const gchar *display_name,
1822                                                   GtkWindow *window)
1823 {
1824         /* Do not change the application name if the widget has not
1825            the focus. This callback could be called even if the folder
1826            view has not the focus, because the handled signal could be
1827            emitted when the folder view is redrawn */
1828         if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
1829                 if (display_name)
1830                         gtk_window_set_title (window, display_name);
1831                 else
1832                         gtk_window_set_title (window, " ");
1833         }
1834 }
1835
1836 void
1837 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
1838 {
1839         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1840         modest_msg_edit_window_select_contacts (window);
1841 }