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