110a26f6533ea1b8e33d3d7842e83c808e507311
[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 <glib/gprintf.h>
36 #include <string.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
44 #include "modest-protocol-info.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include "modest-debug.h"
48 #include <tny-mime-part.h>
49 #include <tny-camel-folder.h>
50 #include <tny-camel-imap-folder.h>
51 #include <tny-camel-pop-folder.h>
52
53 #ifdef MODEST_PLATFORM_MAEMO
54 #include "maemo/modest-osso-state-saving.h"
55 #include "maemo/modest-hildon-includes.h"
56 #include "maemo/modest-connection-specific-smtp-window.h"
57 #endif /* MODEST_PLATFORM_MAEMO */
58 #include <modest-utils.h>
59
60 #include "widgets/modest-ui-constants.h"
61 #include <widgets/modest-main-window.h>
62 #include <widgets/modest-msg-view-window.h>
63 #include <widgets/modest-account-view-window.h>
64 #include <widgets/modest-details-dialog.h>
65 #include <widgets/modest-attachments-view.h>
66 #include "widgets/modest-folder-view.h"
67 #include "widgets/modest-global-settings-dialog.h"
68 #include "modest-account-mgr-helpers.h"
69 #include "modest-mail-operation.h"
70 #include "modest-text-utils.h"
71
72 #ifdef MODEST_HAVE_EASYSETUP
73 #include "easysetup/modest-easysetup-wizard.h"
74 #endif /* MODEST_HAVE_EASYSETUP */
75
76 #include <modest-widget-memory.h>
77 #include <tny-error.h>
78 #include <tny-simple-list.h>
79 #include <tny-msg-view.h>
80 #include <tny-device.h>
81 #include <tny-merge-folder.h>
82
83 #include <gtkhtml/gtkhtml.h>
84
85 typedef struct _GetMsgAsyncHelper {     
86         ModestWindow *window;
87         ModestMailOperation *mail_op;
88         TnyIterator *iter;
89         guint num_ops;
90         GFunc func;     
91         gpointer user_data;
92 } GetMsgAsyncHelper;
93
94 typedef enum _ReplyForwardAction {
95         ACTION_REPLY,
96         ACTION_REPLY_TO_ALL,
97         ACTION_FORWARD
98 } ReplyForwardAction;
99
100 typedef struct _ReplyForwardHelper {
101         guint reply_forward_type;
102         ReplyForwardAction action;
103         gchar *account_name;
104         GtkWidget *parent_window;
105 } ReplyForwardHelper;
106
107 typedef struct _MoveToHelper {
108         GtkTreeRowReference *reference;
109         GtkWidget *banner;
110 } MoveToHelper;
111
112 typedef struct _PasteAsAttachmentHelper {
113         ModestMsgEditWindow *window;
114         GtkWidget *banner;
115 } PasteAsAttachmentHelper;
116
117
118 /*
119  * The do_headers_action uses this kind of functions to perform some
120  * action to each member of a list of headers
121  */
122 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
123
124 static void     do_headers_action     (ModestWindow *win, 
125                                        HeadersFunc func,
126                                        gpointer user_data);
127
128 static void     open_msg_cb            (ModestMailOperation *mail_op, 
129                                         TnyHeader *header, 
130                                         gboolean canceled,
131                                         TnyMsg *msg,
132                                         GError *err,
133                                         gpointer user_data);
134
135 static void     reply_forward_cb       (ModestMailOperation *mail_op, 
136                                         TnyHeader *header, 
137                                         gboolean canceled,
138                                         TnyMsg *msg,
139                                         GError *err,
140                                         gpointer user_data);
141
142 static void     reply_forward          (ReplyForwardAction action, ModestWindow *win);
143
144 static void     folder_refreshed_cb    (ModestMailOperation *mail_op, 
145                                         TnyFolder *folder, 
146                                         gpointer user_data);
147
148 static void     on_send_receive_finished (ModestMailOperation  *mail_op, 
149                                           gpointer user_data);
150
151 static gint header_list_count_uncached_msgs (TnyList *header_list);
152
153 static gboolean connect_to_get_msg (ModestWindow *win,
154                                     gint num_of_uncached_msgs,
155                                     TnyAccount *account);
156
157 static gboolean remote_folder_is_pop (const TnyFolderStore *folder);
158
159 static gboolean msgs_already_deleted_from_server ( TnyList *headers,
160                                                    const TnyFolderStore *src_folder);
161
162 static void     do_create_folder (GtkWindow *window, 
163                                   TnyFolderStore *parent_folder, 
164                                   const gchar *suggested_name);
165
166 static GtkWidget* get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog);
167
168
169 /*
170  * This function checks whether a TnyFolderStore is a pop account
171  */
172 static gboolean
173 remote_folder_is_pop (const TnyFolderStore *folder)
174 {
175         const gchar *proto = NULL;
176         TnyAccount *account = NULL;
177
178         g_return_val_if_fail (TNY_IS_FOLDER_STORE(folder), FALSE);
179
180         if (TNY_IS_ACCOUNT (folder)) {
181                 account = TNY_ACCOUNT(folder);
182                 g_object_ref(account);
183         } else if (TNY_IS_FOLDER (folder)) {
184                 account = tny_folder_get_account(TNY_FOLDER(folder));
185         }
186
187         if (!account && !TNY_IS_ACCOUNT(account)) {
188                 g_warning ("%s: could not get account", __FUNCTION__);
189                 return FALSE;
190         }
191         
192         proto = tny_account_get_proto(account);
193         g_object_unref (account);
194
195         return proto &&
196           (modest_protocol_info_get_transport_store_protocol (proto) == MODEST_PROTOCOL_STORE_POP);
197 }
198
199 /*
200  * This functions checks whether if a list of messages are already
201  * deleted from the server: that is, if the server is a POP account
202  * and all messages are already cached.
203  */
204 static gboolean
205 msgs_already_deleted_from_server (TnyList *headers, const TnyFolderStore *src_folder)
206 {
207         g_return_val_if_fail (TNY_IS_FOLDER_STORE(src_folder), FALSE);
208         g_return_val_if_fail (TNY_IS_LIST(headers), FALSE);
209
210         gboolean src_is_pop = remote_folder_is_pop (src_folder);
211         gint uncached_msgs = header_list_count_uncached_msgs (headers);
212
213         return (src_is_pop && !uncached_msgs);
214 }
215
216
217 /* FIXME: this should be merged with the similar code in modest-account-view-window */
218 /* Show the account creation wizard dialog.
219  * returns: TRUE if an account was created. FALSE if the user cancelled.
220  */
221 gboolean
222 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
223 {
224         gboolean result = FALSE;        
225         GtkWindow *dialog, *wizard;
226         gint dialog_response;
227
228         /* Show the easy-setup wizard: */       
229         dialog = modest_window_mgr_get_modal (modest_runtime_get_window_mgr());
230         if (dialog) {
231                 /* old wizard is active already; 
232                  */
233                 gtk_window_present (GTK_WINDOW(dialog));
234                 return FALSE;
235         }
236         
237
238         /* there is no such wizard yet */       
239         wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
240         modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), wizard);
241
242         /* always present a main window in the background 
243          * we do it here, so we cannot end up with two wizards (as this
244          * function might be called in modest_window_mgr_get_main_window as well */
245         if (!win) 
246                 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
247                                                          TRUE);  /* create if not existent */
248         
249         /* make sure the mainwindow is visible */
250         gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
251         gtk_widget_show_all (GTK_WIDGET(win));
252         gtk_window_present (GTK_WINDOW(win));
253         
254         dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
255         gtk_widget_destroy (GTK_WIDGET (wizard));
256         if (gtk_events_pending ())
257                 gtk_main_iteration ();
258
259         if (dialog_response == GTK_RESPONSE_CANCEL) {
260                 result = FALSE;
261         } else {
262                 /* Check whether an account was created: */
263                 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
264         }
265         return result;
266 }
267
268
269 void   
270 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
271 {
272         GtkWidget *about;
273         const gchar *authors[] = {
274                 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
275                 NULL
276         };
277         about = gtk_about_dialog_new ();
278         gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
279         gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
280         gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
281                                         _("Copyright (c) 2006, Nokia Corporation\n"
282                                           "All rights reserved."));
283         gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
284                                        _("a modest e-mail client\n\n"
285                                          "design and implementation: Dirk-Jan C. Binnema\n"
286                                          "contributions from the fine people at KC and Ig\n"
287                                          "uses the tinymail email framework written by Philip van Hoof"));
288         gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
289         gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
290         gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
291         gtk_window_set_modal (GTK_WINDOW (about), TRUE);
292         
293         gtk_dialog_run (GTK_DIALOG (about));
294         gtk_widget_destroy(about);
295 }
296
297 /*
298  * Gets the list of currently selected messages. If the win is the
299  * main window, then it returns a newly allocated list of the headers
300  * selected in the header view. If win is the msg view window, then
301  * the value returned is a list with just a single header.
302  *
303  * The caller of this funcion must free the list.
304  */
305 static TnyList *
306 get_selected_headers (ModestWindow *win)
307 {
308         if (MODEST_IS_MAIN_WINDOW(win)) {
309                 GtkWidget *header_view;         
310                 
311                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
312                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
313                 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
314                 
315         } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
316                 /* for MsgViewWindows, we simply return a list with one element */
317                 TnyHeader *header;
318                 TnyList *list = NULL;
319                 
320                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
321                 if (header != NULL) {
322                         list = tny_simple_list_new ();
323                         tny_list_prepend (list, G_OBJECT(header));
324                         g_object_unref (G_OBJECT(header));
325                 }
326
327                 return list;
328
329         } else
330                 return NULL;
331 }
332
333 static GtkTreeRowReference *
334 get_next_after_selected_headers (ModestHeaderView *header_view)
335 {
336         GtkTreeSelection *sel;
337         GList *selected_rows, *node;
338         GtkTreePath *path;
339         GtkTreeRowReference *result;
340         GtkTreeModel *model;
341
342         model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
343         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
344         selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
345
346         if (selected_rows == NULL)
347                 return NULL;
348
349         node = g_list_last (selected_rows);
350         path = gtk_tree_path_copy ((GtkTreePath *) node->data);
351         gtk_tree_path_next (path);
352
353         result = gtk_tree_row_reference_new (model, path);
354
355         gtk_tree_path_free (path);
356         g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
357         g_list_free (selected_rows);
358
359         return result;
360 }
361
362 static void
363 headers_action_mark_as_read (TnyHeader *header,
364                              ModestWindow *win,
365                              gpointer user_data)
366 {
367         TnyHeaderFlags flags;
368
369         g_return_if_fail (TNY_IS_HEADER(header));
370
371         flags = tny_header_get_flags (header);
372         if (flags & TNY_HEADER_FLAG_SEEN) return;
373         tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
374 }
375
376 static void
377 headers_action_mark_as_unread (TnyHeader *header,
378                                ModestWindow *win,
379                                gpointer user_data)
380 {
381         TnyHeaderFlags flags;
382
383         g_return_if_fail (TNY_IS_HEADER(header));
384
385         flags = tny_header_get_flags (header);
386         if (flags & TNY_HEADER_FLAG_SEEN)  {
387                 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
388         }
389 }
390
391 /** After deleing a message that is currently visible in a window, 
392  * show the next message from the list, or close the window if there are no more messages.
393  **/
394 void 
395 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
396 {
397         /* Close msg view window or select next */
398         if (modest_msg_view_window_last_message_selected (win) &&
399                 modest_msg_view_window_first_message_selected (win)) {
400                 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
401         } else if (!modest_msg_view_window_select_next_message (win) &&
402                    !modest_msg_view_window_select_previous_message (win)) {
403                 gboolean ret_value;
404                 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);       
405         }
406 }
407
408
409 void
410 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
411 {
412         TnyList *header_list = NULL;
413         TnyIterator *iter = NULL;
414         TnyHeader *header = NULL;
415         gchar *message = NULL;
416         gchar *desc = NULL;
417         gint response;
418         ModestWindowMgr *mgr;
419         GtkWidget *header_view = NULL;
420
421         g_return_if_fail (MODEST_IS_WINDOW(win));
422         
423         /* Check first if the header view has the focus */
424         if (MODEST_IS_MAIN_WINDOW (win)) {
425                 header_view = 
426                         modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
427                                                              MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
428                 if (!gtk_widget_is_focus (header_view))
429                         return;
430         }
431         
432         /* Get the headers, either from the header view (if win is the main window),
433          * or from the message view window: */
434         header_list = get_selected_headers (win);
435         if (!header_list) return;
436                         
437         /* Check if any of the headers are already opened, or in the process of being opened */
438         if (MODEST_IS_MAIN_WINDOW (win)) {
439                 gint opened_headers = 0;
440
441                 iter = tny_list_create_iterator (header_list);
442                 mgr = modest_runtime_get_window_mgr ();
443                 while (!tny_iterator_is_done (iter)) {
444                         header = TNY_HEADER (tny_iterator_get_current (iter));
445                         if (header) {
446                                 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
447                                         opened_headers++;
448                                 g_object_unref (header);
449                         }
450                         tny_iterator_next (iter);
451                 }
452                 g_object_unref (iter);
453
454                 if (opened_headers > 0) {
455                         gchar *msg;
456
457                         msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), 
458                                                opened_headers);
459
460                         modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
461                         
462                         g_free (msg);
463                         g_object_unref (header_list);
464                         return;
465                 }
466         }
467
468         /* Select message */
469         if (tny_list_get_length(header_list) == 1) {
470                 iter = tny_list_create_iterator (header_list);
471                 header = TNY_HEADER (tny_iterator_get_current (iter));
472                 if (header) {
473                         desc = g_strdup_printf ("%s", tny_header_get_subject (header)); 
474                         g_object_unref (header);
475                 }
476
477                 g_object_unref (iter);
478         }
479         message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages", 
480                                            tny_list_get_length(header_list)), desc);
481
482         /* Confirmation dialog */
483         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
484                                                             message);
485         
486
487         if (response == GTK_RESPONSE_OK) {      
488                 ModestWindow *main_window = NULL;
489                 ModestWindowMgr *mgr = NULL;
490                 GtkTreeModel *model = NULL;
491                 GtkTreeSelection *sel = NULL;
492                 GList *sel_list = NULL, *tmp = NULL;
493                 GtkTreeRowReference *next_row_reference = NULL;
494                 GtkTreeRowReference *prev_row_reference = NULL;
495                 GtkTreePath *next_path = NULL;
496                 GtkTreePath *prev_path = NULL;
497                 ModestMailOperation *mail_op = NULL;
498
499                 /* Find last selected row */                    
500                 if (MODEST_IS_MAIN_WINDOW (win)) {
501                         model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
502                         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
503                         sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
504                         for (tmp=sel_list; tmp; tmp=tmp->next) {
505                                 if (tmp->next == NULL) {
506                                         prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
507                                         next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
508
509                                         gtk_tree_path_prev (prev_path);
510                                         gtk_tree_path_next (next_path);
511
512                                         prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
513                                         next_row_reference = gtk_tree_row_reference_new (model, next_path);
514                                 }
515                         }
516                 }
517                 
518                 /* Disable window dimming management */
519                 modest_window_disable_dimming (MODEST_WINDOW(win));
520
521                 /* Remove each header. If it's a view window header_view == NULL */
522                 mail_op = modest_mail_operation_new ((GObject *) win);
523                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
524                                                  mail_op);
525                 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
526                 g_object_unref (mail_op);
527                 
528                 /* Enable window dimming management */
529                 if (sel != NULL) {
530                         gtk_tree_selection_unselect_all (sel);
531                 }
532                 modest_window_enable_dimming (MODEST_WINDOW(win));
533                 
534                 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
535                         modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
536                         
537                         /* Get main window */
538                         mgr = modest_runtime_get_window_mgr ();
539                         main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
540                 } else {                        
541                         /* Move cursor to next row */
542                         main_window = win; 
543
544                         /* Select next or previous row */
545                         if (gtk_tree_row_reference_valid (next_row_reference)) {
546 /*                              next_path = gtk_tree_row_reference_get_path (row_reference); */
547                                 gtk_tree_selection_select_path (sel, next_path);
548                         }
549                         else if (gtk_tree_row_reference_valid (prev_row_reference)) {                           
550                                 gtk_tree_selection_select_path (sel, prev_path);
551                         }
552
553                         /* Free */
554                         if (next_row_reference != NULL) 
555                                 gtk_tree_row_reference_free (next_row_reference);
556                         if (next_path != NULL) 
557                                 gtk_tree_path_free (next_path);                         
558                         if (prev_row_reference != NULL) 
559                                 gtk_tree_row_reference_free (prev_row_reference);
560                         if (prev_path != NULL) 
561                                 gtk_tree_path_free (prev_path);                         
562                 }
563                 
564                 /* Update toolbar dimming state */
565                 if (main_window)
566                         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
567
568                 /* Free */
569                 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
570                 g_list_free (sel_list);
571         }
572
573         /* Free*/
574         g_free(message);
575         g_free(desc);
576         g_object_unref (header_list);
577 }
578
579
580
581
582 /* delete either message or folder, based on where we are */
583 void
584 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
585 {
586         g_return_if_fail (MODEST_IS_WINDOW(win));
587         
588         /* Check first if the header view has the focus */
589         if (MODEST_IS_MAIN_WINDOW (win)) {
590                 GtkWidget *w;
591                 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
592                                                          MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
593                 if (gtk_widget_is_focus (w)) {
594                         modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
595                         return;
596                 }
597         }
598         modest_ui_actions_on_delete_message (action, win);
599 }
600
601
602
603 void
604 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
605 {       
606         ModestWindowMgr *mgr = NULL;
607         
608 #ifdef MODEST_PLATFORM_MAEMO
609         modest_osso_save_state();
610 #endif /* MODEST_PLATFORM_MAEMO */
611
612         g_debug ("closing down, clearing %d item(s) from operation queue",
613                  modest_mail_operation_queue_num_elements
614                  (modest_runtime_get_mail_operation_queue()));
615
616         /* cancel all outstanding operations */
617         modest_mail_operation_queue_cancel_all 
618                 (modest_runtime_get_mail_operation_queue());
619         
620         g_debug ("queue has been cleared");
621
622
623         /* Check if there are opened editing windows */ 
624         mgr = modest_runtime_get_window_mgr ();
625         modest_window_mgr_close_all_windows (mgr);
626
627         /* note: when modest-tny-account-store is finalized,
628            it will automatically set all network connections
629            to offline */
630
631 /*      gtk_main_quit (); */
632 }
633
634 void
635 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
636 {
637         gboolean ret_value;
638
639         g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
640
641 /*      if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
642 /*              gtk_widget_destroy (GTK_WIDGET (win)); */
643 /*      } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
644 /*              gboolean ret_value; */
645 /*              g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
646 /*      } else if (MODEST_IS_WINDOW (win)) { */
647 /*              gtk_widget_destroy (GTK_WIDGET (win)); */
648 /*      } else { */
649 /*              g_return_if_reached (); */
650 /*      } */
651 }
652
653 void
654 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
655 {
656         GtkClipboard *clipboard = NULL;
657         gchar *selection = NULL;
658
659         clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
660         selection = gtk_clipboard_wait_for_text (clipboard);
661
662         /* Question: why is the clipboard being used here? 
663          * It doesn't really make a lot of sense. */
664
665         if (selection)
666         {
667                 modest_address_book_add_address (selection);
668                 g_free (selection);
669         }
670 }
671
672 void
673 modest_ui_actions_on_accounts (GtkAction *action, 
674                                ModestWindow *win)
675 {
676         /* This is currently only implemented for Maemo */
677         if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
678                 if (!modest_ui_actions_run_account_setup_wizard (win)) 
679                         g_debug ("%s: wizard was already running", __FUNCTION__);
680                 
681                 return;
682         } else {
683                 /* Show the list of accounts */
684                 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
685                 gtk_window_set_transient_for (account_win, GTK_WINDOW (win));
686                 
687                 /* The accounts dialog must be modal */
688                 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), account_win);
689                 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win)); 
690         }
691 }
692
693 #ifdef MODEST_PLATFORM_MAEMO
694 static void
695 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
696 {
697         /* Save any changes. */
698         modest_connection_specific_smtp_window_save_server_accounts (
699                         MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window));
700         gtk_widget_destroy (GTK_WIDGET (window));
701 }
702 #endif
703
704
705 void
706 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
707 {
708         /* This is currently only implemented for Maemo,
709          * because it requires an API (libconic) to detect different connection 
710          * possiblities.
711          */
712 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
713         
714         /* Create the window if necessary: */
715         GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
716         modest_connection_specific_smtp_window_fill_with_connections (
717                 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window), 
718                 modest_runtime_get_account_mgr());
719
720         /* Show the window: */  
721         gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
722         gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
723         gtk_widget_show (specific_window);
724     
725         /* Save changes when the window is hidden: */
726         g_signal_connect (specific_window, "hide", 
727                 G_CALLBACK (on_smtp_servers_window_hide), win);
728 #endif /* MODEST_PLATFORM_MAEMO */
729 }
730
731 void
732 modest_ui_actions_compose_msg(ModestWindow *win,
733                               const gchar *to_str,
734                               const gchar *cc_str,
735                               const gchar *bcc_str,
736                               const gchar *subject_str,
737                               const gchar *body_str,
738                               GSList *attachments)
739 {
740         gchar *account_name = NULL;
741         TnyMsg *msg = NULL;
742         TnyAccount *account = NULL;
743         TnyFolder *folder = NULL;
744         gchar *from_str = NULL, *signature = NULL, *body = NULL;
745         gboolean use_signature = FALSE;
746         ModestWindow *msg_win = NULL;
747         ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
748         ModestTnyAccountStore *store = modest_runtime_get_account_store();
749
750         account_name = modest_account_mgr_get_default_account(mgr);
751         if (!account_name) {
752                 g_printerr ("modest: no account found\n");
753                 goto cleanup;
754         }
755         account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
756         if (!account) {
757                 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
758                 goto cleanup;
759         }
760         folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
761         if (!folder) {
762                 g_printerr ("modest: failed to find Drafts folder\n");
763                 goto cleanup;
764         }
765         from_str = modest_account_mgr_get_from_string (mgr, account_name);
766         if (!from_str) {
767                 g_printerr ("modest: failed get from string for '%s'\n", account_name);
768                 goto cleanup;
769         }
770
771         signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
772         if (body_str != NULL) {
773                 body = use_signature ? g_strconcat(body_str, "\n", signature, NULL) : g_strdup(body_str);
774         } else {
775                 body = use_signature ? g_strconcat("\n", signature, NULL) : g_strdup("");
776         }
777
778         msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL);
779         if (!msg) {
780                 g_printerr ("modest: failed to create new msg\n");
781                 goto cleanup;
782         }
783
784         /* Create and register edit window */
785         /* This is destroyed by TODO. */
786         msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
787         while (attachments) {
788                 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
789                                                        attachments->data);
790                 attachments = g_slist_next(attachments);
791         }
792         modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win);
793         gtk_widget_show_all (GTK_WIDGET (msg_win));
794
795 cleanup:
796         g_free (from_str);
797         g_free (signature);
798         g_free (body);
799         g_free (account_name);
800         if (account) g_object_unref (G_OBJECT(account));
801         if (folder) g_object_unref (G_OBJECT(folder));
802         if (msg_win) g_object_unref (G_OBJECT(msg_win));
803         if (msg) g_object_unref (G_OBJECT(msg));
804 }
805
806 void
807 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
808 {
809         /* if there are no accounts yet, just show the wizard */
810         if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
811                 if (!modest_ui_actions_run_account_setup_wizard (win))
812                         return;
813                 
814         modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL);
815 }
816
817 void
818 modest_ui_actions_on_new_msg_or_folder (GtkAction *action, ModestWindow *win)
819 {
820         g_return_if_fail (MODEST_IS_WINDOW (win));
821
822         /* Check first if the folder view has the focus */
823         if (MODEST_IS_MAIN_WINDOW (win)) {
824                 GtkWidget *w;
825                 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
826                                                          MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
827                 if (gtk_widget_is_focus (w)) {
828                         modest_ui_actions_on_new_folder (action, MODEST_MAIN_WINDOW(win));
829                         return;
830                 }
831         }
832
833         modest_ui_actions_on_new_msg (action, win);
834 }
835
836
837 gboolean 
838 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
839                                        TnyHeader *header,
840                                        TnyMsg *msg)
841 {
842         ModestMailOperationStatus status;
843
844         /* If there is no message or the operation was not successful */
845         status = modest_mail_operation_get_status (mail_op);
846         if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
847
848                 /* Remove the header from the preregistered uids */
849                 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),  
850                                                      header);
851
852                 return FALSE;
853         }
854
855         return TRUE;
856 }
857
858 static void
859 open_msg_cb (ModestMailOperation *mail_op, 
860              TnyHeader *header,  
861              gboolean canceled,
862              TnyMsg *msg, 
863              GError *err,
864              gpointer user_data)
865 {
866         ModestWindowMgr *mgr = NULL;
867         ModestWindow *parent_win = NULL;
868         ModestWindow *win = NULL;
869         TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
870         gchar *account = NULL;
871         TnyFolder *folder;
872         gboolean open_in_editor = FALSE;
873         
874         /* Do nothing if there was any problem with the mail
875            operation. The error will be shown by the error_handler of
876            the mail operation */
877         if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
878                 return;
879
880         parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
881         folder = tny_header_get_folder (header);
882
883         /* Mark header as read */
884         headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
885
886         /* Gets folder type (OUTBOX headers will be opened in edit window */
887         if (modest_tny_folder_is_local_folder (folder)) {
888                 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
889                 if (folder_type == TNY_FOLDER_TYPE_INVALID)
890                         g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
891         }
892
893                 
894         if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
895                 TnyTransportAccount *traccount = NULL;
896                 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
897                 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
898                 if (traccount) {
899                         ModestTnySendQueue *send_queue = NULL;
900                         ModestTnySendQueueStatus status;
901                         char *msg_id;
902                         account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
903                                                    TNY_ACCOUNT(traccount)));
904                         send_queue = modest_runtime_get_send_queue(traccount);
905                         msg_id = modest_tny_send_queue_get_msg_id (header);
906                         status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
907                         /* Only open messages in outbox with the editor if they are in Failed state */
908                         if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
909                                 open_in_editor = TRUE;
910                         }
911                         g_free(msg_id);
912                         g_object_unref(traccount);
913                 } else {
914                         g_warning("Cannot get transport account for message in outbox!!");
915                 }
916         } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
917                 open_in_editor = TRUE; /* Open in editor if the message is in the Drafts folder */
918         }
919
920         /* Get account */
921         if (!account)
922                 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
923         if (!account)
924                 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
925         
926         if (open_in_editor) {
927                 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
928                 const gchar *from_header = NULL;
929
930                 from_header = tny_header_get_from (header);
931
932                 /* we cannot edit without a valid account... */
933                 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
934                         if (!modest_ui_actions_run_account_setup_wizard(parent_win))
935                                 goto cleanup;
936                 }
937                 
938                 if (from_header) {
939                         GSList *accounts = modest_account_mgr_account_names (mgr, TRUE);
940                         GSList *node = NULL;
941                         for (node = accounts; node != NULL; node = g_slist_next (node)) {
942                                 gchar *from = modest_account_mgr_get_from_string (mgr, node->data);
943                                 
944                                 if (from && (strcmp (from_header, from) == 0)) {
945                                         g_free (account);
946                                         account = g_strdup (node->data);
947                                         g_free (from);
948                                         break;
949                                 }
950                                 g_free (from);
951                         }
952                         g_slist_foreach (accounts, (GFunc) g_free, NULL);
953                         g_slist_free (accounts);
954                 }
955
956                 win = modest_msg_edit_window_new (msg, account, TRUE);
957
958
959                 /* Show banner */
960                 modest_platform_information_banner_with_timeout
961                         (NULL, NULL, _("mail_ib_opening_draft_message"), 1200);
962
963         } else {
964                 gchar *uid = modest_tny_folder_get_header_unique_id (header);
965                 
966                 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
967                         GtkWidget *header_view;
968                         GtkTreeSelection *sel;
969                         GList *sel_list = NULL;
970                         GtkTreeModel *model;
971                         
972                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
973                                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
974
975                         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
976                         sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
977
978                         if (sel_list != NULL) {
979                                 GtkTreeRowReference *row_reference;
980
981                                 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
982                                 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
983                                 g_list_free (sel_list);
984                                 
985                                 win = modest_msg_view_window_new_with_header_model (
986                                                 msg, account, (const gchar*) uid,
987                                                 model, row_reference);
988                                 gtk_tree_row_reference_free (row_reference);
989                         } else {
990                                 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
991                         }
992                 } else {
993                         win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
994                 }
995                 g_free (uid);
996         }
997         
998         /* Register and show new window */
999         if (win != NULL) {
1000                 mgr = modest_runtime_get_window_mgr ();
1001                 modest_window_mgr_register_window (mgr, win);
1002                 g_object_unref (win);
1003                 gtk_widget_show_all (GTK_WIDGET(win));
1004         }
1005
1006         /* Update toolbar dimming state */
1007         if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1008                 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1009         }
1010
1011 cleanup:
1012         /* Free */
1013         g_free(account);
1014         g_object_unref (parent_win);
1015         g_object_unref (folder);
1016 }
1017
1018 void
1019 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
1020                                                gpointer user_data)
1021 {
1022         const GError *error;
1023         GObject *win = NULL;
1024         const gchar *err_msg = (const gchar *) user_data;
1025
1026         win = modest_mail_operation_get_source (mail_op);
1027         error = modest_mail_operation_get_error (mail_op);
1028
1029         /* Show error */
1030         modest_platform_run_information_dialog ((GtkWindow *) win, err_msg);
1031
1032         if (win)
1033                 g_object_unref (win);
1034 }
1035
1036 /**
1037  * Returns the account a list of headers belongs to. It returns a
1038  * *new* reference so don't forget to unref it
1039  */
1040 static TnyAccount*
1041 get_account_from_header_list (TnyList *headers)
1042 {
1043         TnyAccount *account = NULL;
1044
1045         if (tny_list_get_length (headers) > 0) {
1046                 TnyIterator *iter = tny_list_create_iterator (headers);
1047                 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1048                 TnyFolder *folder = tny_header_get_folder (header);
1049                 account = tny_folder_get_account (folder);
1050                 g_object_unref (folder);
1051                 g_object_unref (header);
1052                 g_object_unref (iter);
1053         }
1054         return account;
1055 }
1056
1057 static void 
1058 foreach_unregister_headers (gpointer data,
1059                             gpointer user_data)
1060 {
1061         ModestWindowMgr *mgr = (ModestWindowMgr *) user_data;
1062         TnyHeader *header = TNY_HEADER (data);
1063
1064         modest_window_mgr_unregister_header (mgr, header);
1065 }
1066
1067 static void
1068 open_msgs_performer(gboolean canceled, 
1069                     GError *err,
1070                     GtkWindow *parent_window,
1071                     TnyAccount *account,
1072                     gpointer user_data)
1073 {
1074         ModestMailOperation *mail_op = NULL;
1075         const gchar *proto_name;
1076         gchar *error_msg;
1077         ModestTransportStoreProtocol proto;
1078         TnyList *not_opened_headers;
1079         TnyConnectionStatus status;
1080
1081         not_opened_headers = TNY_LIST (user_data);
1082
1083         status = tny_account_get_connection_status (account);
1084         if (err || canceled) {
1085                 /* Unregister the already registered headers */
1086                 tny_list_foreach (not_opened_headers, foreach_unregister_headers, 
1087                                   modest_runtime_get_window_mgr ());
1088                 goto clean;
1089         }
1090
1091         /* Get the error message depending on the protocol */
1092         proto_name = tny_account_get_proto (account);
1093         if (proto_name != NULL) {
1094                 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
1095         } else {
1096                 proto = MODEST_PROTOCOL_STORE_MAILDIR;
1097         }
1098         
1099         /* Create the error messages */
1100         if (tny_list_get_length (not_opened_headers) == 1) {
1101                 if (proto == MODEST_PROTOCOL_STORE_POP) {
1102                         error_msg = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1103                 } else if (proto == MODEST_PROTOCOL_STORE_IMAP) {
1104                         TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1105                         TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1106                         error_msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
1107                                                      tny_header_get_subject (header));
1108                         g_object_unref (header);
1109                         g_object_unref (iter);
1110                 } else {
1111                         error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1112                 }
1113         } else {
1114                 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1115         }
1116
1117         /* Create the mail operation */
1118         mail_op = 
1119                 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1120                                                                modest_ui_actions_get_msgs_full_error_handler,
1121                                                                error_msg, g_free);
1122         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1123                                          mail_op);
1124                 
1125         modest_mail_operation_get_msgs_full (mail_op,
1126                                              not_opened_headers,
1127                                              open_msg_cb,
1128                                              NULL,
1129                                              NULL);
1130
1131         /* Frees */
1132  clean:
1133         if (mail_op)
1134                 g_object_unref (mail_op);
1135         g_object_unref (not_opened_headers);
1136         g_object_unref (account);
1137 }
1138
1139 /*
1140  * This function is used by both modest_ui_actions_on_open and
1141  * modest_ui_actions_on_header_activated. This way we always do the
1142  * same when trying to open messages.
1143  */
1144 static void
1145 open_msgs_from_headers (TnyList *headers, ModestWindow *win)
1146 {
1147         ModestWindowMgr *mgr = NULL;
1148         TnyIterator *iter = NULL, *iter_not_opened = NULL;
1149         TnyList *not_opened_headers = NULL;
1150         TnyHeaderFlags flags = 0;
1151         TnyAccount *account;
1152         gint uncached_msgs = 0;
1153                 
1154         g_return_if_fail (headers != NULL);
1155
1156         /* Check that only one message is selected for opening */
1157         if (tny_list_get_length (headers) != 1) {
1158                 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1159                                                         _("mcen_ib_select_one_message"));
1160                 return;
1161         }
1162
1163         mgr = modest_runtime_get_window_mgr ();
1164         iter = tny_list_create_iterator (headers);
1165
1166         /* Get the account */
1167         account = get_account_from_header_list (headers);
1168         
1169         /* Look if we already have a message view for each header. If
1170            true, then remove the header from the list of headers to
1171            open */
1172         not_opened_headers = tny_simple_list_new ();
1173         while (!tny_iterator_is_done (iter)) {
1174
1175                 ModestWindow *window = NULL;
1176                 TnyHeader *header = NULL;
1177                 gboolean found = FALSE;
1178                 
1179                 header = TNY_HEADER (tny_iterator_get_current (iter));
1180                 if (header)
1181                         flags = tny_header_get_flags (header);
1182
1183                 window = NULL;
1184                 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1185                 
1186                 /* Do not open again the message and present the
1187                    window to the user */
1188                 if (found) {
1189                         if (window)
1190                                 gtk_window_present (GTK_WINDOW (window));
1191                         else
1192                                 /* the header has been registered already, we don't do
1193                                  * anything but wait for the window to come up*/
1194                                 g_debug ("header %p already registered, waiting for window", header);
1195                 } else {
1196                         tny_list_append (not_opened_headers, G_OBJECT (header));
1197                 }
1198
1199                 if (header)
1200                         g_object_unref (header);
1201
1202                 tny_iterator_next (iter);
1203         }
1204         g_object_unref (iter);
1205         iter = NULL;
1206
1207         /* Open each message */
1208         if (tny_list_get_length (not_opened_headers) == 0)
1209                 goto cleanup;
1210         
1211         /* If some messages would have to be downloaded, ask the user to 
1212          * make a connection. It's generally easier to do this here (in the mainloop) 
1213          * than later in a thread:
1214          */
1215         if (tny_list_get_length (not_opened_headers) > 0) {
1216                 uncached_msgs = header_list_count_uncached_msgs (not_opened_headers);
1217
1218                 if (uncached_msgs > 0) {
1219                         /* Allways download if we are online. */
1220                         if (!tny_device_is_online (modest_runtime_get_device ())) {
1221                                 gint response;
1222
1223                                 /* If ask for user permission to download the messages */
1224                                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1225                                                                                     ngettext("mcen_nc_get_msg",
1226                                                                                              "mcen_nc_get_msgs",
1227                                                                                              uncached_msgs));
1228
1229                                 /* End if the user does not want to continue */
1230                                 if (response == GTK_RESPONSE_CANCEL)
1231                                         goto cleanup;
1232                         }
1233                 }
1234         }
1235         
1236         /* Register the headers before actually creating the windows: */
1237         iter_not_opened = tny_list_create_iterator (not_opened_headers);
1238         while (!tny_iterator_is_done (iter_not_opened)) {
1239                 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1240                 if (header) {
1241                         modest_window_mgr_register_header (mgr, header, NULL);
1242                         g_object_unref (header);
1243                 }
1244                 tny_iterator_next (iter_not_opened);
1245         }
1246         g_object_unref (iter_not_opened);
1247         iter_not_opened = NULL;
1248
1249         /* Connect to the account and perform */
1250         if (uncached_msgs > 0) {
1251                 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account), 
1252                                                      open_msgs_performer, g_object_ref (not_opened_headers));
1253         } else {
1254                 /* Call directly the performer, do not need to connect */
1255                 open_msgs_performer (FALSE, NULL, (GtkWindow *) win, g_object_ref (account),
1256                                      g_object_ref (not_opened_headers));
1257         }
1258 cleanup:
1259         /* Clean */
1260         if (account)
1261                 g_object_unref (account);
1262         if (not_opened_headers)
1263                 g_object_unref (not_opened_headers);
1264 }
1265
1266 void
1267 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1268 {
1269         TnyList *headers;
1270
1271         /* Get headers */
1272         headers = get_selected_headers (win);
1273         if (!headers)
1274                 return;
1275
1276         /* Open them */
1277         open_msgs_from_headers (headers, win);
1278
1279         g_object_unref(headers);
1280 }
1281
1282
1283 static void
1284 free_reply_forward_helper (gpointer data)
1285 {
1286         ReplyForwardHelper *helper;
1287
1288         helper = (ReplyForwardHelper *) data;
1289         g_free (helper->account_name);
1290         g_slice_free (ReplyForwardHelper, helper);
1291 }
1292
1293 static void
1294 reply_forward_cb (ModestMailOperation *mail_op,  
1295                   TnyHeader *header, 
1296                   gboolean canceled,
1297                   TnyMsg *msg,
1298                   GError *err,
1299                   gpointer user_data)
1300 {
1301         TnyMsg *new_msg;
1302         ReplyForwardHelper *rf_helper;
1303         ModestWindow *msg_win = NULL;
1304         ModestEditType edit_type;
1305         gchar *from = NULL;
1306         TnyAccount *account = NULL;
1307         ModestWindowMgr *mgr = NULL;
1308         gchar *signature = NULL;
1309         gboolean use_signature;
1310
1311         /* If there was any error. The mail operation could be NULL,
1312            this means that we already have the message downloaded and
1313            that we didn't do a mail operation to retrieve it */
1314         if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1315                 return;
1316                         
1317         g_return_if_fail (user_data != NULL);
1318         rf_helper = (ReplyForwardHelper *) user_data;
1319
1320         from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1321                                                    rf_helper->account_name);
1322         signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(), 
1323                                                       rf_helper->account_name, 
1324                                                       &use_signature);
1325
1326         /* Create reply mail */
1327         switch (rf_helper->action) {
1328         case ACTION_REPLY:
1329                 new_msg = 
1330                         modest_tny_msg_create_reply_msg (msg, header, from, signature,
1331                                                          rf_helper->reply_forward_type,
1332                                                          MODEST_TNY_MSG_REPLY_MODE_SENDER);
1333                 break;
1334         case ACTION_REPLY_TO_ALL:
1335                 new_msg = 
1336                         modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1337                                                          MODEST_TNY_MSG_REPLY_MODE_ALL);
1338                 edit_type = MODEST_EDIT_TYPE_REPLY;
1339                 break;
1340         case ACTION_FORWARD:
1341                 new_msg = 
1342                         modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1343                 edit_type = MODEST_EDIT_TYPE_FORWARD;
1344                 break;
1345         default:
1346                 g_return_if_reached ();
1347                 return;
1348         }
1349
1350         g_free (signature);
1351
1352         if (!new_msg) {
1353                 g_printerr ("modest: failed to create message\n");
1354                 goto cleanup;
1355         }
1356
1357         account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1358                                                                        rf_helper->account_name,
1359                                                                        TNY_ACCOUNT_TYPE_STORE);
1360         if (!account) {
1361                 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1362                 goto cleanup;
1363         }
1364
1365         /* Create and register the windows */
1366         msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1367         mgr = modest_runtime_get_window_mgr ();
1368         modest_window_mgr_register_window (mgr, msg_win);
1369
1370         if (rf_helper->parent_window != NULL) {
1371                 gdouble parent_zoom;
1372
1373                 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1374                 modest_window_set_zoom (msg_win, parent_zoom);
1375         }
1376
1377         /* Show edit window */
1378         gtk_widget_show_all (GTK_WIDGET (msg_win));
1379
1380 cleanup:
1381         if (msg_win)
1382                 g_object_unref (msg_win);
1383         if (new_msg)
1384                 g_object_unref (G_OBJECT (new_msg));
1385         if (account)
1386                 g_object_unref (G_OBJECT (account));
1387 /*      g_object_unref (msg); */
1388         free_reply_forward_helper (rf_helper);
1389 }
1390
1391 /* Checks a list of headers. If any of them are not currently
1392  * downloaded (CACHED) then returns TRUE else returns FALSE.
1393  */
1394 static gint
1395 header_list_count_uncached_msgs (TnyList *header_list)
1396 {
1397         TnyIterator *iter;
1398         gint uncached_messages = 0;
1399
1400         iter = tny_list_create_iterator (header_list);
1401         while (!tny_iterator_is_done (iter)) {
1402                 TnyHeader *header;
1403
1404                 header = TNY_HEADER (tny_iterator_get_current (iter));
1405                 if (header) {
1406                         if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1407                                 uncached_messages ++;
1408                         g_object_unref (header);
1409                 }
1410
1411                 tny_iterator_next (iter);
1412         }
1413         g_object_unref (iter);
1414
1415         return uncached_messages;
1416 }
1417
1418 /* Returns FALSE if the user does not want to download the
1419  * messages. Returns TRUE if the user allowed the download.
1420  */
1421 static gboolean
1422 connect_to_get_msg (ModestWindow *win,
1423                     gint num_of_uncached_msgs,
1424                     TnyAccount *account)
1425 {
1426         GtkResponseType response;
1427
1428         /* Allways download if we are online. */
1429         if (tny_device_is_online (modest_runtime_get_device ()))
1430                 return TRUE;
1431
1432         /* If offline, then ask for user permission to download the messages */
1433         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1434                         ngettext("mcen_nc_get_msg",
1435                         "mcen_nc_get_msgs",
1436                         num_of_uncached_msgs));
1437
1438         if (response == GTK_RESPONSE_CANCEL)
1439                 return FALSE;
1440
1441         return modest_platform_connect_and_wait((GtkWindow *) win, account);
1442 }
1443
1444 /*
1445  * Common code for the reply and forward actions
1446  */
1447 static void
1448 reply_forward (ReplyForwardAction action, ModestWindow *win)
1449 {
1450         ModestMailOperation *mail_op = NULL;
1451         TnyList *header_list = NULL;
1452         ReplyForwardHelper *rf_helper = NULL;
1453         guint reply_forward_type;
1454         gboolean continue_download = TRUE;
1455         gboolean do_retrieve = TRUE;
1456         
1457         g_return_if_fail (MODEST_IS_WINDOW(win));
1458
1459         /* we need an account when editing */
1460         if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1461                 if (!modest_ui_actions_run_account_setup_wizard (win))
1462                         return;
1463         }
1464         
1465         header_list = get_selected_headers (win);
1466         if (!header_list)
1467                 return;
1468
1469         reply_forward_type = 
1470                 modest_conf_get_int (modest_runtime_get_conf (),
1471                                      (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1472                                      NULL);
1473
1474         /* check if we need to download msg before asking about it */
1475         do_retrieve = (action == ACTION_FORWARD) ||
1476                         (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1477
1478         if (do_retrieve){
1479                 gint num_of_unc_msgs;
1480
1481                 /* check that the messages have been previously downloaded */
1482                 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1483                 /* If there are any uncached message ask the user
1484                  * whether he/she wants to download them. */
1485                 if (num_of_unc_msgs) {
1486                         TnyAccount *account = get_account_from_header_list (header_list);
1487                         continue_download = connect_to_get_msg (win, num_of_unc_msgs, account);
1488                         g_object_unref (account);
1489                 }
1490         }
1491
1492         if (!continue_download) {
1493                 g_object_unref (header_list);
1494                 return;
1495         }
1496         
1497         /* We assume that we can only select messages of the
1498            same folder and that we reply all of them from the
1499            same account. In fact the interface currently only
1500            allows single selection */
1501         
1502         /* Fill helpers */
1503         rf_helper = g_slice_new0 (ReplyForwardHelper);
1504         rf_helper->reply_forward_type = reply_forward_type;
1505         rf_helper->action = action;
1506         rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1507         
1508         if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1509                 rf_helper->parent_window = GTK_WIDGET (win);
1510         if (!rf_helper->account_name)
1511                 rf_helper->account_name =
1512                         modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1513
1514         if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1515                 TnyMsg *msg;
1516                 TnyHeader *header;
1517                 /* Get header and message. Do not free them here, the
1518                    reply_forward_cb must do it */
1519                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1520                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1521                 if (!msg || !header) {
1522                         if (msg)
1523                                 g_object_unref (msg);
1524                         g_printerr ("modest: no message found\n");
1525                         return;
1526                 } else {
1527                         reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1528                 }
1529                 if (header)
1530                         g_object_unref (header);
1531         } else {
1532                 TnyHeader *header;
1533                 TnyIterator *iter;
1534
1535                 /* Only reply/forward to one message */
1536                 iter = tny_list_create_iterator (header_list);
1537                 header = TNY_HEADER (tny_iterator_get_current (iter));
1538                 g_object_unref (iter);
1539
1540                 if (header) {
1541                         /* Retrieve messages */
1542                         if (do_retrieve) {
1543                                 mail_op = 
1544                                         modest_mail_operation_new_with_error_handling (G_OBJECT(win),
1545                                                                                        modest_ui_actions_get_msgs_full_error_handler, 
1546                                                                                        NULL, NULL);
1547                                 modest_mail_operation_queue_add (
1548                                         modest_runtime_get_mail_operation_queue (), mail_op);
1549                                 
1550                                 modest_mail_operation_get_msg (mail_op,
1551                                                                header,
1552                                                                reply_forward_cb,
1553                                                                rf_helper);
1554                                 /* Clean */
1555                                 g_object_unref(mail_op);
1556                         } else {
1557                                 /* we put a ref here to prevent double unref as the reply
1558                                  * forward callback unrefs the header at its end */
1559                                 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1560                         }
1561
1562
1563                         g_object_unref (header);
1564                 }
1565
1566         }
1567
1568         /* Free */
1569         g_object_unref (header_list);
1570 }
1571
1572 void
1573 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1574 {
1575         g_return_if_fail (MODEST_IS_WINDOW(win));
1576
1577         reply_forward (ACTION_REPLY, win);
1578 }
1579
1580 void
1581 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1582 {
1583         g_return_if_fail (MODEST_IS_WINDOW(win));
1584
1585         reply_forward (ACTION_FORWARD, win);
1586 }
1587
1588 void
1589 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1590 {
1591         g_return_if_fail (MODEST_IS_WINDOW(win));
1592
1593         reply_forward (ACTION_REPLY_TO_ALL, win);
1594 }
1595
1596 void 
1597 modest_ui_actions_on_next (GtkAction *action, 
1598                            ModestWindow *window)
1599 {
1600         if (MODEST_IS_MAIN_WINDOW (window)) {
1601                 GtkWidget *header_view;
1602
1603                 header_view = modest_main_window_get_child_widget (
1604                                 MODEST_MAIN_WINDOW(window),
1605                                 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1606                 if (!header_view)
1607                         return;
1608         
1609                 modest_header_view_select_next (
1610                                 MODEST_HEADER_VIEW(header_view)); 
1611         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1612                 modest_msg_view_window_select_next_message (
1613                                 MODEST_MSG_VIEW_WINDOW (window));
1614         } else {
1615                 g_return_if_reached ();
1616         }
1617 }
1618
1619 void 
1620 modest_ui_actions_on_prev (GtkAction *action, 
1621                            ModestWindow *window)
1622 {
1623         g_return_if_fail (MODEST_IS_WINDOW(window));
1624
1625         if (MODEST_IS_MAIN_WINDOW (window)) {
1626                 GtkWidget *header_view;
1627                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1628                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1629                 if (!header_view)
1630                         return;
1631                 
1632                 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view)); 
1633         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1634                 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1635         } else {
1636                 g_return_if_reached ();
1637         }
1638 }
1639
1640 void 
1641 modest_ui_actions_on_sort (GtkAction *action, 
1642                            ModestWindow *window)
1643 {
1644         g_return_if_fail (MODEST_IS_WINDOW(window));
1645
1646         if (MODEST_IS_MAIN_WINDOW (window)) {
1647                 GtkWidget *header_view;
1648                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1649                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1650                 if (!header_view) {
1651                         modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1652
1653                         return;
1654                 }
1655
1656                 /* Show sorting dialog */
1657                 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);     
1658         }
1659 }
1660
1661 static void
1662 new_messages_arrived (ModestMailOperation *self, 
1663                       TnyList *new_headers,
1664                       gpointer user_data)
1665 {
1666         GObject *source;
1667         gboolean show_visual_notifications;
1668
1669         source = modest_mail_operation_get_source (self);
1670         show_visual_notifications = (source) ? FALSE : TRUE;
1671         if (source)
1672                 g_object_unref (source);
1673
1674         /* Notify new messages have been downloaded. If the
1675            send&receive was invoked by the user then do not show any
1676            visual notification, only play a sound and activate the LED
1677            (for the Maemo version) */
1678         if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
1679                 modest_platform_on_new_headers_received (new_headers, 
1680                                                          show_visual_notifications);
1681
1682 }
1683
1684 gboolean
1685 retrieve_all_messages_cb (GObject *source,
1686                           guint num_msgs,
1687                           guint retrieve_limit)
1688 {
1689         GtkWindow *window;
1690         gchar *msg;
1691         gint response;
1692
1693         window = GTK_WINDOW (source);
1694         msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"), 
1695                                num_msgs, retrieve_limit);
1696
1697         /* Ask the user if they want to retrieve all the messages */
1698         response = 
1699                 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
1700                                                                       _("mcen_bd_get_all"),
1701                                                                       _("mcen_bd_newest_only"));
1702         /* Free and return */
1703         g_free (msg);
1704         return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
1705 }
1706
1707 typedef struct {
1708         TnyAccount *account;
1709         ModestWindow *win;
1710         gchar *account_name;
1711 } SendReceiveInfo;
1712
1713 static void
1714 do_send_receive_performer (gboolean canceled, 
1715                            GError *err,
1716                            GtkWindow *parent_window, 
1717                            TnyAccount *account, 
1718                            gpointer user_data)
1719 {
1720         ModestMailOperation *mail_op;
1721         SendReceiveInfo *info;
1722
1723         info = (SendReceiveInfo *) user_data;
1724
1725         if (err || canceled) {
1726                 goto clean;
1727         }
1728
1729         /* Set send/receive operation in progress */    
1730         if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
1731                 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
1732         }
1733         
1734         mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
1735                                                                  modest_ui_actions_send_receive_error_handler,
1736                                                                  NULL, NULL);
1737
1738         if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
1739                 g_signal_connect (G_OBJECT(mail_op), "operation-finished", 
1740                                   G_CALLBACK (on_send_receive_finished), 
1741                                   info->win);
1742
1743         /* Send & receive. */
1744         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1745         modest_mail_operation_update_account (mail_op, info->account_name, (info->win) ? FALSE : TRUE,
1746                                               (info->win) ? retrieve_all_messages_cb : NULL, 
1747                                               new_messages_arrived, info->win);
1748         g_object_unref (G_OBJECT (mail_op));
1749         
1750  clean:
1751         /* Frees */
1752         if (info->account_name)
1753                 g_free (info->account_name);
1754         if (info->win)
1755                 g_object_unref (info->win);
1756         if (info->account)
1757                 g_object_unref (info->account);
1758         g_slice_free (SendReceiveInfo, info);
1759 }
1760
1761 /*
1762  * This function performs the send & receive required actions. The
1763  * window is used to create the mail operation. Typically it should
1764  * always be the main window, but we pass it as argument in order to
1765  * be more flexible.
1766  */
1767 void
1768 modest_ui_actions_do_send_receive (const gchar *account_name, 
1769                                    gboolean force_connection,
1770                                    ModestWindow *win)
1771 {
1772         gchar *acc_name = NULL;
1773         SendReceiveInfo *info;
1774         ModestTnyAccountStore *acc_store;
1775
1776         /* If no account name was provided then get the current account, and if
1777            there is no current account then pick the default one: */
1778         if (!account_name) {
1779                 if (win)
1780                         acc_name = g_strdup (modest_window_get_active_account (win));
1781                 if (!acc_name)
1782                         acc_name  = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1783                 if (!acc_name) {
1784                         g_printerr ("modest: cannot get default account\n");
1785                         return;
1786                 }
1787         } else {
1788                 acc_name = g_strdup (account_name);
1789         }
1790
1791         acc_store = modest_runtime_get_account_store ();
1792
1793         /* Create the info for the connect and perform */
1794         info = g_slice_new (SendReceiveInfo);
1795         info->account_name = acc_name;
1796         info->win = (win) ? g_object_ref (win) : NULL;
1797         info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
1798                                                                      TNY_ACCOUNT_TYPE_STORE);
1799
1800         /* Invoke the connect and perform */
1801         modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL, 
1802                                              force_connection, info->account, 
1803                                              do_send_receive_performer, info);
1804 }
1805
1806
1807 static void
1808 modest_ui_actions_do_cancel_send (const gchar *account_name,  
1809                                   ModestWindow *win)
1810 {
1811         TnyTransportAccount *transport_account;
1812         TnySendQueue *send_queue = NULL;
1813         GError *error = NULL;
1814
1815         /* Get transport account */
1816         transport_account =
1817                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1818                                       (modest_runtime_get_account_store(),
1819                                        account_name,
1820                                        TNY_ACCOUNT_TYPE_TRANSPORT));
1821         if (!transport_account) {
1822                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1823                 goto frees;
1824         }
1825
1826         /* Get send queue*/
1827         send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1828         if (!TNY_IS_SEND_QUEUE(send_queue)) {
1829                 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1830                              MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1831                              "modest: could not find send queue for account\n");
1832         } else {
1833                 /* Cancel the current send */
1834                 tny_account_cancel (TNY_ACCOUNT (transport_account));
1835
1836                 /* Suspend all pending messages */
1837                 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
1838         }
1839
1840  frees:
1841         if (transport_account != NULL) 
1842                 g_object_unref (G_OBJECT (transport_account));
1843 }
1844
1845 static void
1846 modest_ui_actions_cancel_send_all (ModestWindow *win) 
1847 {
1848         GSList *account_names, *iter;
1849
1850         account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), 
1851                                                           TRUE);
1852
1853         iter = account_names;
1854         while (iter) {                  
1855                 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1856                 iter = g_slist_next (iter);
1857         }
1858
1859         modest_account_mgr_free_account_names (account_names);
1860         account_names = NULL;
1861 }
1862
1863 void
1864 modest_ui_actions_cancel_send (GtkAction *action,  ModestWindow *win)
1865
1866 {
1867         /* Check if accounts exist */
1868         gboolean accounts_exist = 
1869                 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1870         
1871         /* If not, allow the user to create an account before trying to send/receive. */
1872         if (!accounts_exist)
1873                 modest_ui_actions_on_accounts (NULL, win);
1874         
1875         /* Cancel all sending operaitons */     
1876         modest_ui_actions_cancel_send_all (win);
1877 }
1878
1879 /*
1880  * Refreshes all accounts. This function will be used by automatic
1881  * updates
1882  */
1883 void
1884 modest_ui_actions_do_send_receive_all (ModestWindow *win, 
1885                                        gboolean force_connection)
1886 {
1887         GSList *account_names, *iter;
1888
1889         account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), 
1890                                                           TRUE);
1891
1892         iter = account_names;
1893         while (iter) {                  
1894                 modest_ui_actions_do_send_receive ((const char*) iter->data, force_connection, win);
1895                 iter = g_slist_next (iter);
1896         }
1897
1898         modest_account_mgr_free_account_names (account_names);
1899         account_names = NULL;
1900 }
1901
1902 /*
1903  * Handler of the click on Send&Receive button in the main toolbar
1904  */
1905 void
1906 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1907 {
1908         /* Check if accounts exist */
1909         gboolean accounts_exist;
1910
1911         accounts_exist =
1912                 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1913         
1914         /* If not, allow the user to create an account before trying to send/receive. */
1915         if (!accounts_exist)
1916                 modest_ui_actions_on_accounts (NULL, win);
1917         
1918         /* Refresh the current folder. The if is always TRUE it's just an extra check */
1919         if (MODEST_IS_MAIN_WINDOW (win)) {
1920                 GtkWidget *folder_view;
1921                 TnyFolderStore *folder_store;
1922
1923                 folder_view = 
1924                         modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win), 
1925                                                              MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1926                 if (!folder_view)
1927                         return;
1928                 
1929                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1930         
1931                 if (folder_store)
1932                         g_object_unref (folder_store);
1933         }       
1934         
1935         /* Refresh the active account. Force the connection if needed */
1936         modest_ui_actions_do_send_receive (NULL, TRUE, win);
1937 }
1938
1939
1940 void
1941 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1942 {
1943         ModestConf *conf;
1944         GtkWidget *header_view;
1945         
1946         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1947
1948         header_view = modest_main_window_get_child_widget (main_window,
1949                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1950         if (!header_view)
1951                 return;
1952
1953         conf = modest_runtime_get_conf ();
1954         
1955         /* what is saved/restored is depending on the style; thus; we save with
1956          * old style, then update the style, and restore for this new style
1957          */
1958         modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1959         
1960         if (modest_header_view_get_style
1961             (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1962                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1963                                               MODEST_HEADER_VIEW_STYLE_TWOLINES);
1964         else
1965                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1966                                               MODEST_HEADER_VIEW_STYLE_DETAILS);
1967
1968         modest_widget_memory_restore (conf, G_OBJECT(header_view),
1969                                       MODEST_CONF_HEADER_VIEW_KEY);
1970 }
1971
1972
1973 void 
1974 modest_ui_actions_on_header_selected (ModestHeaderView *header_view, 
1975                                       TnyHeader *header,
1976                                       ModestMainWindow *main_window)
1977 {
1978         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1979         g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1980         
1981         /* in the case the folder is empty, show the empty folder message and focus
1982          * folder view */
1983         if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1984                 if (modest_header_view_is_empty (header_view)) {
1985                         TnyFolder *folder = modest_header_view_get_folder (header_view);
1986                         GtkWidget *folder_view = 
1987                                 modest_main_window_get_child_widget (main_window,
1988                                                                      MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1989                         if (folder != NULL) 
1990                                 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1991                         gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1992                         return;
1993                 }
1994         }
1995         /* If no header has been selected then exit */
1996         if (!header)
1997                 return;
1998
1999         /* Update focus */
2000         if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2001             gtk_widget_grab_focus (GTK_WIDGET(header_view));
2002
2003         /* Update toolbar dimming state */
2004         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2005 }
2006
2007 void
2008 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2009                                        TnyHeader *header,
2010                                        ModestMainWindow *main_window)
2011 {
2012         TnyList *headers;
2013
2014         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2015
2016         if (!header)
2017                 return;
2018
2019         if (modest_header_view_count_selected_headers (header_view) > 1) {
2020                 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2021                 return;
2022         }
2023
2024
2025 /*      headers = tny_simple_list_new (); */
2026 /*      tny_list_prepend (headers, G_OBJECT (header)); */
2027         headers = modest_header_view_get_selected_headers (header_view);
2028
2029         open_msgs_from_headers (headers, MODEST_WINDOW (main_window));
2030
2031         g_object_unref (headers);
2032 }
2033
2034 static void
2035 set_active_account_from_tny_account (TnyAccount *account,
2036                                      ModestWindow *window)
2037 {
2038         const gchar *server_acc_name = tny_account_get_id (account);
2039         
2040         /* We need the TnyAccount provided by the
2041            account store because that is the one that
2042            knows the name of the Modest account */
2043         TnyAccount *modest_server_account = modest_server_account = 
2044                 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2045                                                              MODEST_TNY_ACCOUNT_STORE_QUERY_ID, 
2046                                                              server_acc_name);
2047         if (!modest_server_account) {
2048                 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2049                 return;
2050         }
2051
2052         /* Update active account, but only if it's not a pseudo-account */
2053         if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2054             (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2055                 const gchar *modest_acc_name = 
2056                         modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2057                 if (modest_acc_name)
2058                         modest_window_set_active_account (window, modest_acc_name);
2059         }
2060         
2061         g_object_unref (modest_server_account);
2062 }
2063
2064
2065 static void
2066 folder_refreshed_cb (ModestMailOperation *mail_op, 
2067                      TnyFolder *folder, 
2068                      gpointer user_data)
2069 {
2070         ModestMainWindow *win = NULL;
2071         GtkWidget *header_view;
2072
2073         g_return_if_fail (TNY_IS_FOLDER (folder));
2074
2075         win = MODEST_MAIN_WINDOW (user_data);
2076         header_view = 
2077                 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2078
2079         if (header_view) {
2080                 TnyFolder *current_folder;
2081
2082                 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
2083                 if (current_folder != NULL && folder != current_folder) {
2084                         g_object_unref (current_folder);
2085                         return;
2086                 } else if (current_folder)
2087                         g_object_unref (current_folder);
2088         }
2089
2090         /* Check if folder is empty and set headers view contents style */
2091         if (tny_folder_get_all_count (folder) == 0)
2092                 modest_main_window_set_contents_style (win,
2093                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2094 }
2095
2096 void 
2097 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2098                                                TnyFolderStore *folder_store, 
2099                                                gboolean selected,
2100                                                ModestMainWindow *main_window)
2101 {
2102         ModestConf *conf;
2103         GtkWidget *header_view;
2104
2105         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2106
2107         header_view = modest_main_window_get_child_widget(main_window,
2108                                                           MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2109         if (!header_view)
2110                 return;
2111         
2112         conf = modest_runtime_get_conf ();
2113
2114         if (TNY_IS_ACCOUNT (folder_store)) {
2115                 if (selected) {
2116                         set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2117                         
2118                         /* Show account details */
2119                         modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2120                 }
2121         } else {
2122                 if (TNY_IS_FOLDER (folder_store) && selected) {
2123                         
2124                         /* Update the active account */
2125                         TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2126                         if (account) {
2127                                 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2128                                 g_object_unref (account);
2129                                 account = NULL;
2130                         }
2131
2132                         /* Set the header style by default, it could
2133                            be changed later by the refresh callback to
2134                            empty */
2135                         modest_main_window_set_contents_style (main_window, 
2136                                                                MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2137
2138                         /* Set folder on header view. This function
2139                            will call tny_folder_refresh_async so we
2140                            pass a callback that will be called when
2141                            finished. We use that callback to set the
2142                            empty view if there are no messages */
2143                         modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2144                                                        TNY_FOLDER (folder_store),
2145                                                        folder_refreshed_cb,
2146                                                        main_window);
2147                         
2148                         /* Restore configuration. We need to do this
2149                            *after* the set_folder because the widget
2150                            memory asks the header view about its
2151                            folder  */
2152                         modest_widget_memory_restore (modest_runtime_get_conf (), 
2153                                                       G_OBJECT(header_view),
2154                                                       MODEST_CONF_HEADER_VIEW_KEY);
2155                 } else {
2156                         /* Update the active account */
2157                         //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
2158                         /* Save only if we're seeing headers */
2159                         if (modest_main_window_get_contents_style (main_window) ==
2160                             MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2161                                 modest_widget_memory_save (conf, G_OBJECT (header_view), 
2162                                                            MODEST_CONF_HEADER_VIEW_KEY);
2163                         modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2164                 }
2165         }
2166
2167         /* Update toolbar dimming state */
2168         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2169 }
2170
2171 void 
2172 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2173                                      ModestWindow *win)
2174 {
2175         GtkWidget *dialog;
2176         gchar *txt, *item;
2177         gboolean online;
2178
2179         item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2180         
2181         online = tny_device_is_online (modest_runtime_get_device());
2182
2183         if (online) {
2184                 /* already online -- the item is simply not there... */
2185                 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2186                                                  GTK_DIALOG_MODAL,
2187                                                  GTK_MESSAGE_WARNING,
2188                                                  GTK_BUTTONS_NONE,
2189                                                  _("The %s you selected cannot be found"),
2190                                                  item);
2191                 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2192                 gtk_dialog_run (GTK_DIALOG(dialog));
2193         } else {
2194                 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2195                                                       GTK_WINDOW (win),
2196                                                       GTK_DIALOG_MODAL,
2197                                                       _("mcen_bd_dialog_cancel"),
2198                                                       GTK_RESPONSE_REJECT,
2199                                                       _("mcen_bd_dialog_ok"),
2200                                                       GTK_RESPONSE_ACCEPT,
2201                                                       NULL);
2202                 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2203                                          "Do you want to get online?"), item);
2204                 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
2205                                     gtk_label_new (txt), FALSE, FALSE, 0);
2206                 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2207                 g_free (txt);
2208
2209                 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2210                 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2211                         /* TODO: Comment about why is this commented out: */
2212                         /* modest_platform_connect_and_wait (); */
2213                 }
2214         }
2215         gtk_widget_destroy (dialog);
2216 }
2217
2218 void
2219 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2220                                      ModestWindow *win)
2221 {
2222         /* g_message ("%s %s", __FUNCTION__, link); */
2223 }       
2224
2225
2226 void
2227 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2228                                         ModestWindow *win)
2229 {
2230         modest_platform_activate_uri (link);
2231 }
2232
2233 void
2234 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2235                                           ModestWindow *win)
2236 {
2237         modest_platform_show_uri_popup (link);
2238 }
2239
2240 void
2241 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2242                                              ModestWindow *win)
2243 {
2244         modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2245 }
2246
2247 void
2248 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2249                                           const gchar *address,
2250                                           ModestWindow *win)
2251 {
2252         /* g_message ("%s %s", __FUNCTION__, address); */
2253 }
2254
2255 static void
2256 on_save_to_drafts_cb (ModestMailOperation *mail_op, 
2257                       TnyMsg *saved_draft,
2258                       gpointer user_data)
2259 {
2260         ModestMsgEditWindow *edit_window;
2261         ModestMainWindow *win;
2262
2263         /* FIXME. Make the header view sensitive again. This is a
2264          * temporary hack. See modest_ui_actions_on_save_to_drafts()
2265          * for details */
2266         win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2267                                          modest_runtime_get_window_mgr(), FALSE));
2268         if (win != NULL) {
2269                 GtkWidget *hdrview = modest_main_window_get_child_widget(
2270                         win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2271                 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2272         }
2273
2274         edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2275
2276         /* It might not be a good idea to do nothing if there was an error,
2277          * so let's at least show a generic error banner. */
2278         /* TODO error while saving attachment, show "Saving draft failed" banner */
2279         if (modest_mail_operation_get_error (mail_op) != NULL) {
2280                 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_op))->message);
2281                 modest_platform_information_banner (NULL, NULL, _("mail_ib_file_operation_failed"));
2282         } else {
2283                 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2284         }
2285         g_object_unref(edit_window);
2286 }
2287
2288 void
2289 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2290 {
2291         TnyTransportAccount *transport_account;
2292         ModestMailOperation *mail_operation;
2293         MsgData *data;
2294         gchar *account_name, *from;
2295         ModestAccountMgr *account_mgr;
2296         char *info_text;
2297
2298         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2299         
2300         data = modest_msg_edit_window_get_msg_data (edit_window);
2301
2302         account_name = g_strdup (data->account_name);
2303         account_mgr = modest_runtime_get_account_mgr();
2304         if (!account_name)
2305                 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2306         if (!account_name) 
2307                 account_name = modest_account_mgr_get_default_account (account_mgr);
2308         if (!account_name) {
2309                 g_printerr ("modest: no account found\n");
2310                 modest_msg_edit_window_free_msg_data (edit_window, data);
2311                 return;
2312         }
2313
2314         if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2315                 account_name = g_strdup (data->account_name);
2316         }
2317
2318         transport_account =
2319                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2320                                       (modest_runtime_get_account_store(),
2321                                        account_name,
2322                                        TNY_ACCOUNT_TYPE_TRANSPORT));
2323         if (!transport_account) {
2324                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2325                 g_free (account_name);
2326                 modest_msg_edit_window_free_msg_data (edit_window, data);
2327                 return;
2328         }
2329         from = modest_account_mgr_get_from_string (account_mgr, account_name);
2330
2331         /* Create the mail operation */         
2332         mail_operation = modest_mail_operation_new (NULL);
2333         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2334
2335         modest_mail_operation_save_to_drafts (mail_operation,
2336                                               transport_account,
2337                                               data->draft_msg,
2338                                               from,
2339                                               data->to, 
2340                                               data->cc, 
2341                                               data->bcc,
2342                                               data->subject, 
2343                                               data->plain_body, 
2344                                               data->html_body,
2345                                               data->attachments,
2346                                               data->images,
2347                                               data->priority_flags,
2348                                               on_save_to_drafts_cb,
2349                                               g_object_ref(edit_window));
2350         info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2351         modest_platform_information_banner (NULL, NULL, info_text);
2352
2353         /* Frees */
2354         g_free (info_text);
2355         g_free (from);
2356         g_free (account_name);
2357         g_object_unref (G_OBJECT (transport_account));
2358         g_object_unref (G_OBJECT (mail_operation));
2359
2360         modest_msg_edit_window_free_msg_data (edit_window, data);
2361         modest_msg_edit_window_reset_modified (edit_window);
2362
2363         /* ** FIXME **
2364          * If the drafts folder is selected then make the header view
2365          * insensitive while the message is being saved to drafts
2366          * (it'll be sensitive again in on_save_to_drafts_cb()). This
2367          * is not very clean but it avoids letting the drafts folder
2368          * in an inconsistent state: the user could edit the message
2369          * being saved and undesirable things would happen.
2370          * In the average case the user won't notice anything at
2371          * all. In the worst case (the user is editing a really big
2372          * file from Drafts) the header view will be insensitive
2373          * during the saving process (10 or 20 seconds, depending on
2374          * the message). Anyway this is just a quick workaround: once
2375          * we find a better solution it should be removed
2376          * See NB#65125 (commend #18) for details.
2377          */
2378         ModestMainWindow *win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2379                 modest_runtime_get_window_mgr(), FALSE));
2380         if (win != NULL) {
2381                 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2382                         win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2383                 if (view != NULL) {
2384                         TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2385                         if (folder) {
2386                                 if (modest_tny_folder_is_local_folder(folder)) {
2387                                         TnyFolderType folder_type;
2388                                         folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2389                                         if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2390                                                 GtkWidget *hdrview = modest_main_window_get_child_widget(
2391                                                         win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2392                                                 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2393                                         }
2394                                 }
2395                         }
2396                         if (folder != NULL) g_object_unref(folder);
2397                 }
2398         }
2399 }
2400
2401 /* For instance, when clicking the Send toolbar button when editing a message: */
2402 void
2403 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2404 {
2405         TnyTransportAccount *transport_account = NULL;
2406
2407         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2408
2409         if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2410                 return;
2411         
2412         /* FIXME: Code added just for testing. The final version will
2413            use the send queue provided by tinymail and some
2414            classifier */
2415         MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2416
2417         ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2418         gchar *account_name = g_strdup (data->account_name);
2419         if (!account_name)
2420                 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2421
2422         if (!account_name) 
2423                 account_name = modest_account_mgr_get_default_account (account_mgr);
2424                 
2425         if (!account_name) {
2426                 modest_msg_edit_window_free_msg_data (edit_window, data);
2427                 /* Run account setup wizard */
2428                 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2429                         return;
2430                 }
2431         }
2432         
2433         /* Get the currently-active transport account for this modest account: */
2434         if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2435                 transport_account = TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2436                                                           (modest_runtime_get_account_store(),
2437                                                            account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2438         }
2439         
2440         if (!transport_account) {
2441                 modest_msg_edit_window_free_msg_data (edit_window, data);
2442                 /* Run account setup wizard */
2443                 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2444                         return;
2445         }
2446         
2447         gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2448
2449         /* Create the mail operation */
2450         ModestMailOperation *mail_operation = modest_mail_operation_new (NULL);
2451         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2452
2453         modest_mail_operation_send_new_mail (mail_operation,
2454                                              transport_account,
2455                                              data->draft_msg,
2456                                              from,
2457                                              data->to, 
2458                                              data->cc, 
2459                                              data->bcc,
2460                                              data->subject, 
2461                                              data->plain_body, 
2462                                              data->html_body,
2463                                              data->attachments,
2464                                              data->images,
2465                                              data->priority_flags);
2466
2467         if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2468                 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2469
2470                                              
2471         /* Free data: */
2472         g_free (from);
2473         g_free (account_name);
2474         g_object_unref (G_OBJECT (transport_account));
2475         g_object_unref (G_OBJECT (mail_operation));
2476
2477         modest_msg_edit_window_free_msg_data (edit_window, data);
2478         modest_msg_edit_window_set_sent (edit_window, TRUE);
2479
2480         /* Save settings and close the window: */
2481         modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2482 }
2483
2484 void 
2485 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2486                                   ModestMsgEditWindow *window)
2487 {
2488         ModestMsgEditFormatState *format_state = NULL;
2489
2490         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2491         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2492
2493         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2494                 return;
2495
2496         format_state = modest_msg_edit_window_get_format_state (window);
2497         g_return_if_fail (format_state != NULL);
2498
2499         format_state->bold = gtk_toggle_action_get_active (action);
2500         modest_msg_edit_window_set_format_state (window, format_state);
2501         g_free (format_state);
2502         
2503 }
2504
2505 void 
2506 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2507                                      ModestMsgEditWindow *window)
2508 {
2509         ModestMsgEditFormatState *format_state = NULL;
2510
2511         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2512         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2513
2514         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2515                 return;
2516
2517         format_state = modest_msg_edit_window_get_format_state (window);
2518         g_return_if_fail (format_state != NULL);
2519
2520         format_state->italics = gtk_toggle_action_get_active (action);
2521         modest_msg_edit_window_set_format_state (window, format_state);
2522         g_free (format_state);
2523         
2524 }
2525
2526 void 
2527 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2528                                      ModestMsgEditWindow *window)
2529 {
2530         ModestMsgEditFormatState *format_state = NULL;
2531
2532         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2533         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2534
2535         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2536                 return;
2537
2538         format_state = modest_msg_edit_window_get_format_state (window);
2539         g_return_if_fail (format_state != NULL);
2540
2541         format_state->bullet = gtk_toggle_action_get_active (action);
2542         modest_msg_edit_window_set_format_state (window, format_state);
2543         g_free (format_state);
2544         
2545 }
2546
2547 void 
2548 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2549                                      GtkRadioAction *selected,
2550                                      ModestMsgEditWindow *window)
2551 {
2552         ModestMsgEditFormatState *format_state = NULL;
2553         GtkJustification value;
2554
2555         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2556
2557         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2558                 return;
2559
2560         value = gtk_radio_action_get_current_value (selected);
2561
2562         format_state = modest_msg_edit_window_get_format_state (window);
2563         g_return_if_fail (format_state != NULL);
2564
2565         format_state->justification = value;
2566         modest_msg_edit_window_set_format_state (window, format_state);
2567         g_free (format_state);
2568 }
2569
2570 void 
2571 modest_ui_actions_on_select_editor_color (GtkAction *action,
2572                                           ModestMsgEditWindow *window)
2573 {
2574         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2575         g_return_if_fail (GTK_IS_ACTION (action));
2576
2577         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2578                 return;
2579
2580         modest_msg_edit_window_select_color (window);
2581 }
2582
2583 void 
2584 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2585                                                      ModestMsgEditWindow *window)
2586 {
2587         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2588         g_return_if_fail (GTK_IS_ACTION (action));
2589
2590         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2591                 return;
2592
2593         modest_msg_edit_window_select_background_color (window);
2594 }
2595
2596 void 
2597 modest_ui_actions_on_insert_image (GtkAction *action,
2598                                    ModestMsgEditWindow *window)
2599 {
2600         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2601         g_return_if_fail (GTK_IS_ACTION (action));
2602
2603         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2604                 return;
2605
2606         modest_msg_edit_window_insert_image (window);
2607 }
2608
2609 void 
2610 modest_ui_actions_on_attach_file (GtkAction *action,
2611                                   ModestMsgEditWindow *window)
2612 {
2613         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2614         g_return_if_fail (GTK_IS_ACTION (action));
2615
2616         modest_msg_edit_window_offer_attach_file (window);
2617 }
2618
2619 void 
2620 modest_ui_actions_on_remove_attachments (GtkAction *action,
2621                                          ModestMsgEditWindow *window)
2622 {
2623         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2624         g_return_if_fail (GTK_IS_ACTION (action));
2625
2626         modest_msg_edit_window_remove_attachments (window, NULL);
2627 }
2628
2629 static void
2630 do_create_folder_cb (ModestMailOperation *mail_op,
2631                      TnyFolderStore *parent_folder, 
2632                      TnyFolder *new_folder,
2633                      gpointer user_data)
2634 {
2635         gchar *suggested_name = (gchar *) user_data;
2636         GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
2637
2638         if (modest_mail_operation_get_error (mail_op)) {
2639                 /* Show an error */
2640                 modest_platform_information_banner (GTK_WIDGET (source_win), NULL,
2641                                                     _("mail_in_ui_folder_create_error"));
2642
2643                 /* Try again */
2644                 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
2645         } else {
2646                 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
2647                  * FIXME: any other? */         
2648                 GtkWidget *folder_view;
2649
2650                 if (MODEST_IS_MAIN_WINDOW(source_win)) 
2651                         folder_view = 
2652                                 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
2653                                                                      MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2654                 else
2655                         folder_view =
2656                                 get_folder_view_from_move_to_dialog (GTK_WIDGET(source_win));
2657                 
2658                 /* Select the newly created folder */
2659                 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
2660                                                   new_folder, FALSE);
2661                 g_object_unref (new_folder);
2662         }
2663         /* Free. Note that the first time it'll be NULL so noop */
2664         g_free (suggested_name);
2665         g_object_unref (source_win);
2666 }
2667
2668 static void
2669 do_create_folder (GtkWindow *parent_window, 
2670                   TnyFolderStore *parent_folder, 
2671                   const gchar *suggested_name)
2672 {
2673         gint result;
2674         gchar *folder_name = NULL;
2675
2676         result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2677                                                         parent_folder,
2678                                                         (gchar *) suggested_name,
2679                                                         &folder_name);
2680         
2681         if (result == GTK_RESPONSE_ACCEPT) {
2682                 ModestMailOperation *mail_op;
2683                 
2684                 mail_op  = modest_mail_operation_new (G_OBJECT(parent_window));
2685                         
2686                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
2687                                                  mail_op);
2688                 modest_mail_operation_create_folder (mail_op,
2689                                                      parent_folder,
2690                                                      (const gchar *) folder_name,
2691                                                      do_create_folder_cb,
2692                                                      folder_name);
2693                 g_object_unref (mail_op);
2694         }
2695 }
2696
2697 static void
2698 create_folder_performer (gboolean canceled, 
2699                          GError *err,
2700                          GtkWindow *parent_window, 
2701                          TnyAccount *account, 
2702                          gpointer user_data)
2703 {
2704         TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
2705
2706         if (canceled || err) {
2707                 goto frees;
2708         }
2709
2710         /* Run the new folder dialog */
2711         do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
2712
2713  frees:
2714         g_object_unref (parent_folder);
2715 }
2716
2717 static void
2718 modest_ui_actions_create_folder(GtkWidget *parent_window,
2719                                 GtkWidget *folder_view)
2720 {
2721         TnyFolderStore *parent_folder;
2722
2723         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2724         
2725         if (parent_folder) {
2726                 /* The parent folder will be freed in the callback */
2727                 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window), 
2728                                                                TRUE,
2729                                                                parent_folder,
2730                                                                create_folder_performer, 
2731                                                                parent_folder);
2732         }
2733 }
2734
2735 void 
2736 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2737 {
2738         GtkWidget *folder_view;
2739         
2740         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2741
2742         folder_view = modest_main_window_get_child_widget (main_window,
2743                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2744         if (!folder_view)
2745                 return;
2746
2747         modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2748 }
2749
2750 static void
2751 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2752                                                gpointer user_data)
2753 {
2754         ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2755         const GError *error = NULL;
2756         const gchar *message = NULL;
2757         
2758         /* Get error message */
2759         error = modest_mail_operation_get_error (mail_op);
2760         if (!error)
2761                 g_return_if_reached ();
2762
2763         switch (error->code) {
2764         case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2765                 message = _CS("ckdg_ib_folder_already_exists");
2766                 break;
2767         default:
2768                 g_warning ("%s: BUG: unexpected error:[%d]: %s", __FUNCTION__,
2769                            error->code, error->message);
2770                 return;
2771         }
2772
2773         modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2774 }
2775
2776 typedef struct {
2777         TnyFolderStore *folder;
2778         gchar *new_name;
2779 } RenameFolderInfo;
2780
2781 static void
2782 on_rename_folder_cb (ModestMailOperation *mail_op, 
2783                      TnyFolder *new_folder,
2784                      gpointer user_data)
2785 {
2786         /* Select now */
2787         modest_folder_view_select_folder (MODEST_FOLDER_VIEW (user_data),
2788                                           new_folder, FALSE);
2789 }
2790
2791 static void
2792 on_rename_folder_performer (gboolean canceled, 
2793                             GError *err, 
2794                             GtkWindow *parent_window, 
2795                             TnyAccount *account, 
2796                             gpointer user_data)
2797 {
2798         ModestMailOperation *mail_op = NULL;
2799         GtkTreeSelection *sel = NULL;
2800         GtkWidget *folder_view = NULL;
2801         RenameFolderInfo *data = (RenameFolderInfo*)user_data;
2802
2803         if (!canceled && (err == NULL) && MODEST_IS_MAIN_WINDOW(parent_window)) {
2804
2805                 folder_view = modest_main_window_get_child_widget (
2806                                 MODEST_MAIN_WINDOW (parent_window),
2807                                 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2808
2809                 mail_op = 
2810                         modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2811                                         modest_ui_actions_rename_folder_error_handler,
2812                                         parent_window, NULL);
2813
2814                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2815                                 mail_op);
2816
2817                 /* Clear the headers view */
2818                 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2819                 gtk_tree_selection_unselect_all (sel);
2820
2821                 /* Actually rename the folder */
2822                 modest_mail_operation_rename_folder (mail_op,
2823                                                      TNY_FOLDER (data->folder),
2824                                                      (const gchar *) (data->new_name),
2825                                                      on_rename_folder_cb,
2826                                                      folder_view);
2827         }
2828
2829         g_object_unref (mail_op);
2830         g_free (data->new_name);
2831         g_free (data);
2832 }
2833
2834 void 
2835 modest_ui_actions_on_rename_folder (GtkAction *action,
2836                                      ModestMainWindow *main_window)
2837 {
2838         TnyFolderStore *folder;
2839         GtkWidget *folder_view;
2840         GtkWidget *header_view; 
2841
2842         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2843
2844         folder_view = modest_main_window_get_child_widget (main_window,
2845                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2846         if (!folder_view)
2847                 return;
2848
2849         header_view = modest_main_window_get_child_widget (main_window,
2850                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2851         
2852         if (!header_view)
2853                 return;
2854
2855         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2856
2857         if (!folder)
2858                 return;
2859
2860         if (TNY_IS_FOLDER (folder)) {
2861                 gchar *folder_name;
2862                 gint response;
2863                 const gchar *current_name;
2864                 TnyFolderStore *parent;
2865                 gboolean do_rename = TRUE;
2866
2867                 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2868                 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2869                 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), 
2870                                                                      parent, current_name, 
2871                                                                      &folder_name);
2872                 g_object_unref (parent);
2873
2874                 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2875                         do_rename = FALSE;
2876                 } else {
2877                         RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
2878                         rename_folder_data->folder = folder;
2879                         rename_folder_data->new_name = folder_name;
2880                         modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window), TRUE,
2881                                         folder, on_rename_folder_performer, rename_folder_data);
2882                 }
2883         }
2884         g_object_unref (folder);
2885 }
2886
2887 static void
2888 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2889                                                gpointer user_data)
2890 {
2891         GObject *win = modest_mail_operation_get_source (mail_op);
2892
2893         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2894                                                 _("mail_in_ui_folder_delete_error"));
2895         g_object_unref (win);
2896 }
2897
2898 typedef struct {
2899         TnyFolderStore *folder;
2900         gboolean move_to_trash;
2901 } DeleteFolderInfo;
2902
2903 static void
2904 on_delete_folder_cb (gboolean canceled, 
2905                   GError *err,
2906                   GtkWindow *parent_window, 
2907                   TnyAccount *account, 
2908                   gpointer user_data)
2909 {
2910         DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
2911         GtkWidget *folder_view;
2912         ModestMailOperation *mail_op;
2913         GtkTreeSelection *sel;
2914         
2915         if (!MODEST_IS_MAIN_WINDOW(parent_window) || canceled || (err!=NULL)) {
2916                 g_object_unref (G_OBJECT (info->folder));
2917                 g_free (info);
2918         }
2919         
2920         folder_view = modest_main_window_get_child_widget (
2921                         MODEST_MAIN_WINDOW (parent_window),
2922                         MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2923
2924         /* Unselect the folder before deleting it to free the headers */
2925         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2926         gtk_tree_selection_unselect_all (sel);
2927
2928         /* Create the mail operation */
2929         mail_op =
2930                 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2931                                 modest_ui_actions_delete_folder_error_handler,
2932                                 NULL, NULL);
2933
2934         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2935                         mail_op);
2936         modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
2937         
2938         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2939
2940         g_object_unref (G_OBJECT (mail_op));
2941         g_object_unref (G_OBJECT (info->folder));
2942         g_free (info);
2943 }
2944
2945 static void
2946 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2947 {
2948         TnyFolderStore *folder;
2949         GtkWidget *folder_view;
2950         gint response;
2951         gchar *message;
2952         
2953         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2954
2955         folder_view = modest_main_window_get_child_widget (main_window,
2956                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2957         if (!folder_view)
2958                 return;
2959
2960         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2961
2962         /* Show an error if it's an account */
2963         if (!TNY_IS_FOLDER (folder)) {
2964                 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2965                                                         _("mail_in_ui_folder_delete_error"));
2966                 g_object_unref (G_OBJECT (folder));
2967                 return;
2968         }
2969
2970         /* Ask the user */      
2971         message =  g_strdup_printf (_("mcen_nc_delete_folder_text"), 
2972                                     tny_folder_get_name (TNY_FOLDER (folder)));
2973         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2974                                                             (const gchar *) message);
2975         g_free (message);
2976
2977         if (response == GTK_RESPONSE_OK) {
2978                 DeleteFolderInfo *info;
2979                 info = g_new0(DeleteFolderInfo, 1);
2980                 info->folder = folder;
2981                 info->move_to_trash = move_to_trash;
2982                 g_object_ref (G_OBJECT (info->folder));
2983                 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
2984                 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (main_window), 
2985                                                                TRUE,
2986                                                                TNY_FOLDER_STORE (account), 
2987                                                                on_delete_folder_cb, info);
2988                 g_object_unref (account);
2989         }
2990         g_object_unref (G_OBJECT (folder));
2991 }
2992
2993 void 
2994 modest_ui_actions_on_delete_folder (GtkAction *action,
2995                                      ModestMainWindow *main_window)
2996 {
2997         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2998         
2999         delete_folder (main_window, FALSE);
3000 }
3001
3002 void 
3003 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3004 {
3005         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3006         
3007         delete_folder (main_window, TRUE);
3008 }
3009
3010
3011 static void
3012 show_error (GtkWidget *parent_widget, const gchar* text)
3013 {
3014         modest_platform_information_banner(parent_widget, NULL, text);
3015         
3016 #if 0
3017         GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
3018         /*
3019           GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
3020           (GtkDialogFlags)0,
3021           GTK_MESSAGE_ERROR,
3022           GTK_BUTTONS_OK,
3023           text ));
3024         */
3025                  
3026         gtk_dialog_run (dialog);
3027         gtk_widget_destroy (GTK_WIDGET (dialog));
3028 #endif
3029 }
3030
3031 void
3032 modest_ui_actions_on_password_requested (TnyAccountStore *account_store, 
3033                                          const gchar* server_account_name,
3034                                          gchar **username,
3035                                          gchar **password, 
3036                                          gboolean *cancel, 
3037                                          gboolean *remember,
3038                                          ModestMainWindow *main_window)
3039 {
3040         g_return_if_fail(server_account_name);
3041         
3042         /* Initalize output parameters: */
3043         if (cancel)
3044                 *cancel = FALSE;
3045                 
3046         if (remember)
3047                 *remember = TRUE;
3048                 
3049 #ifdef MODEST_PLATFORM_MAEMO
3050         /* Maemo uses a different (awkward) button order,
3051          * It should probably just use gtk_alternative_dialog_button_order ().
3052          */
3053         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3054                                               NULL,
3055                                               GTK_DIALOG_MODAL,
3056                                               _("mcen_bd_dialog_ok"),
3057                                               GTK_RESPONSE_ACCEPT,
3058                                               _("mcen_bd_dialog_cancel"),
3059                                               GTK_RESPONSE_REJECT,
3060                                               NULL);
3061 #else
3062         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3063                                               NULL,
3064                                               GTK_DIALOG_MODAL,
3065                                               GTK_STOCK_CANCEL,
3066                                               GTK_RESPONSE_REJECT,
3067                                               GTK_STOCK_OK,
3068                                               GTK_RESPONSE_ACCEPT,
3069                                               NULL);
3070 #endif /* MODEST_PLATFORM_MAEMO */
3071
3072         modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog));
3073         
3074         gchar *server_name = modest_account_mgr_get_server_account_hostname (
3075                 modest_runtime_get_account_mgr(), server_account_name);
3076         if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3077                 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3078                 if (cancel)
3079                         *cancel = TRUE;
3080                 return;
3081         }
3082         
3083         /* This causes a warning because the logical ID has no %s in it, 
3084          * though the translation does, but there is not much we can do about that: */
3085         gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3086         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3087                             FALSE, FALSE, 0);
3088         g_free (txt);
3089         g_free (server_name);
3090         server_name = NULL;
3091
3092         /* username: */
3093         gchar *initial_username = modest_account_mgr_get_server_account_username (
3094                 modest_runtime_get_account_mgr(), server_account_name);
3095         
3096         GtkWidget *entry_username = gtk_entry_new ();
3097         if (initial_username)
3098                 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3099         /* Dim this if a connection has ever succeeded with this username,
3100          * as per the UI spec: */
3101         const gboolean username_known = 
3102                 modest_account_mgr_get_server_account_username_has_succeeded(
3103                         modest_runtime_get_account_mgr(), server_account_name);
3104         gtk_widget_set_sensitive (entry_username, !username_known);
3105         
3106 #ifdef MODEST_PLATFORM_MAEMO
3107         /* Auto-capitalization is the default, so let's turn it off: */
3108         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3109         
3110         /* Create a size group to be used by all captions.
3111          * Note that HildonCaption does not create a default size group if we do not specify one.
3112          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3113         GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3114         
3115         GtkWidget *caption = hildon_caption_new (sizegroup, 
3116                 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3117         gtk_widget_show (entry_username);
3118         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
3119                 FALSE, FALSE, MODEST_MARGIN_HALF);
3120         gtk_widget_show (caption);
3121 #else 
3122         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3123                             TRUE, FALSE, 0);
3124 #endif /* MODEST_PLATFORM_MAEMO */      
3125                             
3126         /* password: */
3127         GtkWidget *entry_password = gtk_entry_new ();
3128         gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3129         /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3130         
3131 #ifdef MODEST_PLATFORM_MAEMO
3132         /* Auto-capitalization is the default, so let's turn it off: */
3133         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password), 
3134                 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3135         
3136         caption = hildon_caption_new (sizegroup, 
3137                 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3138         gtk_widget_show (entry_password);
3139         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
3140                 FALSE, FALSE, MODEST_MARGIN_HALF);
3141         gtk_widget_show (caption);
3142         g_object_unref (sizegroup);
3143 #else 
3144         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3145                             TRUE, FALSE, 0);
3146 #endif /* MODEST_PLATFORM_MAEMO */      
3147
3148         if (initial_username != NULL)
3149                 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3150                                 
3151 /* This is not in the Maemo UI spec:
3152         remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3153         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3154                             TRUE, FALSE, 0);
3155 */
3156
3157         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3158         
3159         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3160                 if (username) {
3161                         *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3162                         
3163                         modest_account_mgr_set_server_account_username (
3164                                  modest_runtime_get_account_mgr(), server_account_name, 
3165                                  *username);
3166                                  
3167                         const gboolean username_was_changed = 
3168                                 (strcmp (*username, initial_username) != 0);
3169                         if (username_was_changed) {
3170                                 g_warning ("%s: tinymail does not yet support changing the "
3171                                         "username in the get_password() callback.\n", __FUNCTION__);
3172                         }
3173                 }
3174                         
3175                 if (password) {
3176                         *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3177                         
3178                         /* We do not save the password in the configuration, 
3179                          * because this function is only called for passwords that should 
3180                          * not be remembered:
3181                         modest_server_account_set_password (
3182                                  modest_runtime_get_account_mgr(), server_account_name, 
3183                                  *password);
3184                         */
3185                 }
3186                 
3187                 if (cancel)
3188                         *cancel   = FALSE;
3189                         
3190         } else {
3191                 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
3192                 
3193                 if (username)
3194                         *username = NULL;
3195                         
3196                 if (password)
3197                         *password = NULL;
3198                         
3199                 if (cancel)
3200                         *cancel   = TRUE;
3201         }
3202
3203 /* This is not in the Maemo UI spec:
3204         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3205                 *remember = TRUE;
3206         else
3207                 *remember = FALSE;
3208 */
3209
3210         gtk_widget_destroy (dialog);
3211         
3212         /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3213 }
3214
3215 void
3216 modest_ui_actions_on_cut (GtkAction *action,
3217                           ModestWindow *window)
3218 {
3219         GtkWidget *focused_widget;
3220         GtkClipboard *clipboard;
3221
3222         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3223         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3224         if (GTK_IS_EDITABLE (focused_widget)) {
3225                 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3226                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3227                 gtk_clipboard_store (clipboard);
3228         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3229                 GtkTextBuffer *buffer;
3230
3231                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3232                 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3233                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3234                 gtk_clipboard_store (clipboard);
3235         } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3236                 TnyList *header_list = modest_header_view_get_selected_headers (
3237                                 MODEST_HEADER_VIEW (focused_widget));
3238                 gboolean continue_download = FALSE;
3239                 gint num_of_unc_msgs;
3240
3241                 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3242
3243                 if (num_of_unc_msgs) {
3244                         TnyAccount *account = get_account_from_header_list (header_list);
3245                         continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3246                         g_object_unref (account);
3247                 }
3248
3249                 if (num_of_unc_msgs == 0 || continue_download) {
3250 /*                      modest_platform_information_banner (
3251                                         NULL, NULL, _CS("mcen_ib_getting_items"));*/
3252                         modest_header_view_cut_selection (
3253                                         MODEST_HEADER_VIEW (focused_widget));
3254                 }
3255
3256                 g_object_unref (header_list);
3257         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3258                 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3259         }
3260 }
3261
3262 void
3263 modest_ui_actions_on_copy (GtkAction *action,
3264                            ModestWindow *window)
3265 {
3266         GtkClipboard *clipboard;
3267         GtkWidget *focused_widget;
3268         gboolean copied = TRUE;
3269
3270         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3271         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3272
3273         if (GTK_IS_LABEL (focused_widget)) {
3274                 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
3275                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3276                 gtk_clipboard_store (clipboard);
3277         } else if (GTK_IS_EDITABLE (focused_widget)) {
3278                 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3279                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3280                 gtk_clipboard_store (clipboard);
3281         } else if (GTK_IS_HTML (focused_widget)) {
3282                 gtk_html_copy (GTK_HTML (focused_widget));
3283                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3284                 gtk_clipboard_store (clipboard);
3285         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3286                 GtkTextBuffer *buffer;
3287                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3288                 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3289                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3290                 gtk_clipboard_store (clipboard);
3291         } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3292                 TnyList *header_list = modest_header_view_get_selected_headers (
3293                                 MODEST_HEADER_VIEW (focused_widget));
3294                 gboolean continue_download = FALSE;
3295                 gint num_of_unc_msgs;
3296
3297                 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3298
3299                 if (num_of_unc_msgs) {
3300                         TnyAccount *account = get_account_from_header_list (header_list);
3301                         continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3302                         g_object_unref (account);
3303                 }
3304
3305                 if (num_of_unc_msgs == 0 || continue_download) {
3306                         modest_platform_information_banner (
3307                                         NULL, NULL, _CS("mcen_ib_getting_items"));
3308                         modest_header_view_copy_selection (
3309                                         MODEST_HEADER_VIEW (focused_widget));
3310                 } else
3311                         copied = FALSE;
3312
3313                 g_object_unref (header_list);
3314
3315         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3316                 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3317         }
3318
3319         /* Show information banner if there was a copy to clipboard */
3320         if(copied)
3321                 modest_platform_information_banner (
3322                                 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3323 }
3324
3325 void
3326 modest_ui_actions_on_undo (GtkAction *action,
3327                            ModestWindow *window)
3328 {
3329         ModestEmailClipboard *clipboard = NULL;
3330
3331         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3332                 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3333         } else if (MODEST_IS_MAIN_WINDOW (window)) {
3334                 /* Clear clipboard source */
3335                 clipboard = modest_runtime_get_email_clipboard ();
3336                 modest_email_clipboard_clear (clipboard);               
3337         }
3338         else {
3339                 g_return_if_reached ();
3340         }
3341 }
3342
3343 void
3344 modest_ui_actions_on_redo (GtkAction *action,
3345                            ModestWindow *window)
3346 {
3347         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3348                 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3349         }
3350         else {
3351                 g_return_if_reached ();
3352         }
3353 }
3354
3355
3356 static void
3357 destroy_information_note (ModestMailOperation *mail_op, 
3358                           gpointer user_data)
3359 {
3360         /* destroy information note */
3361         gtk_widget_destroy (GTK_WIDGET(user_data));
3362 }
3363
3364 static void
3365 destroy_folder_information_note (ModestMailOperation *mail_op, 
3366                                  TnyFolder *new_folder,
3367                                  gpointer user_data)
3368 {
3369         /* destroy information note */
3370         gtk_widget_destroy (GTK_WIDGET(user_data));
3371 }
3372
3373
3374 static void
3375 paste_as_attachment_free (gpointer data)
3376 {
3377         PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3378
3379         gtk_widget_destroy (helper->banner);
3380         g_object_unref (helper->banner);
3381         g_free (helper);
3382 }
3383
3384 static void
3385 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3386                             TnyHeader *header,
3387                             TnyMsg *msg,
3388                             gpointer userdata)
3389 {
3390         PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3391         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3392
3393         if (msg == NULL)
3394                 return;
3395
3396         modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3397         
3398 }
3399
3400 void
3401 modest_ui_actions_on_paste (GtkAction *action,
3402                             ModestWindow *window)
3403 {
3404         GtkWidget *focused_widget = NULL;
3405         GtkWidget *inf_note = NULL;
3406         ModestMailOperation *mail_op = NULL;
3407
3408         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3409         if (GTK_IS_EDITABLE (focused_widget)) {
3410                 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3411         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3412                 ModestEmailClipboard *e_clipboard = NULL;
3413                 e_clipboard = modest_runtime_get_email_clipboard ();
3414                 if (modest_email_clipboard_cleared (e_clipboard)) {
3415                         GtkTextBuffer *buffer;
3416                         GtkClipboard *clipboard;
3417
3418                         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3419                         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3420                         gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3421                 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3422                         ModestMailOperation *mail_op;
3423                         TnyFolder *src_folder;
3424                         TnyList *data;
3425                         gboolean delete;
3426                         PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3427                         helper->window = MODEST_MSG_EDIT_WINDOW (window);
3428                         helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3429                                                                            _CS("ckct_nw_pasting"));
3430                         modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3431                         mail_op = modest_mail_operation_new (G_OBJECT (window));
3432                         if (helper->banner != NULL) {
3433                                 g_object_ref (G_OBJECT (helper->banner));
3434                                 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3435                                 gtk_widget_show (GTK_WIDGET (helper->banner));
3436                         }
3437
3438                         if (data != NULL) {
3439                                 modest_mail_operation_get_msgs_full (mail_op, 
3440                                                                      data,
3441                                                                      (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3442                                                                      helper,
3443                                                                      paste_as_attachment_free);
3444                         }
3445                 }
3446         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3447                 ModestEmailClipboard *clipboard = NULL;
3448                 TnyFolder *src_folder = NULL;
3449                 TnyFolderStore *folder_store = NULL;
3450                 TnyList *data = NULL;           
3451                 gboolean delete = FALSE;
3452                 
3453                 /* Check clipboard source */
3454                 clipboard = modest_runtime_get_email_clipboard ();
3455                 if (modest_email_clipboard_cleared (clipboard)) 
3456                         return;
3457                 
3458                 /* Get elements to paste */
3459                 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3460
3461                 /* Create a new mail operation */
3462                 mail_op = modest_mail_operation_new (G_OBJECT(window));
3463                 
3464                 /* Get destination folder */
3465                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3466
3467                 /* transfer messages  */
3468                 if (data != NULL) {
3469                         gint response = 0;
3470
3471                         /* Ask for user confirmation */
3472                         response = 
3473                                 modest_ui_actions_msgs_move_to_confirmation (window, 
3474                                                                              TNY_FOLDER (folder_store), 
3475                                                                              delete,
3476                                                                              data);
3477                         
3478                         if (response == GTK_RESPONSE_OK) {
3479                                 /* Launch notification */
3480                                 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL, 
3481                                                                              _CS("ckct_nw_pasting"));
3482                                 if (inf_note != NULL)  {
3483                                         gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3484                                         gtk_widget_show (GTK_WIDGET(inf_note));
3485                                 }
3486
3487                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3488                                 modest_mail_operation_xfer_msgs (mail_op, 
3489                                                                  data,
3490                                                                  TNY_FOLDER (folder_store),
3491                                                                  delete,
3492                                                                  destroy_information_note,
3493                                                                  inf_note);                             
3494                         } else {
3495                                 g_object_unref (mail_op);
3496                         }
3497                         
3498                 } else if (src_folder != NULL) {                        
3499                         /* Launch notification */
3500                         inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL, 
3501                                                                      _CS("ckct_nw_pasting"));
3502                         if (inf_note != NULL)  {
3503                                 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3504                                 gtk_widget_show (GTK_WIDGET(inf_note));
3505                         }
3506                         
3507                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3508                         modest_mail_operation_xfer_folder (mail_op, 
3509                                                            src_folder,
3510                                                            folder_store,
3511                                                            delete,
3512                                                            destroy_folder_information_note,
3513                                                            inf_note);
3514                 }
3515
3516                 /* Free */
3517                 if (data != NULL) 
3518                         g_object_unref (data);
3519                 if (src_folder != NULL) 
3520                         g_object_unref (src_folder);
3521                 if (folder_store != NULL) 
3522                         g_object_unref (folder_store);
3523         }
3524 }
3525
3526
3527 void
3528 modest_ui_actions_on_select_all (GtkAction *action,
3529                                  ModestWindow *window)
3530 {
3531         GtkWidget *focused_widget;
3532
3533         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3534         if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3535                 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3536         } else if (GTK_IS_LABEL (focused_widget)) {
3537                 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3538         } else if (GTK_IS_EDITABLE (focused_widget)) {
3539                 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3540         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3541                 GtkTextBuffer *buffer;
3542                 GtkTextIter start, end;
3543
3544                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3545                 gtk_text_buffer_get_start_iter (buffer, &start);
3546                 gtk_text_buffer_get_end_iter (buffer, &end);
3547                 gtk_text_buffer_select_range (buffer, &start, &end);
3548         } else if (GTK_IS_HTML (focused_widget)) {
3549                 gtk_html_select_all (GTK_HTML (focused_widget));
3550         } else if (MODEST_IS_MAIN_WINDOW (window)) {
3551                 GtkWidget *header_view = focused_widget;
3552                 GtkTreeSelection *selection = NULL;
3553                 
3554                 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3555                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3556                                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3557                 }
3558                                 
3559                 /* Disable window dimming management */
3560                 modest_window_disable_dimming (MODEST_WINDOW(window));
3561                 
3562                 /* Select all messages */
3563                 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3564                 gtk_tree_selection_select_all (selection);
3565
3566                 /* Set focuse on header view */
3567                 gtk_widget_grab_focus (header_view);
3568
3569
3570                 /* Enable window dimming management */
3571                 modest_window_enable_dimming (MODEST_WINDOW(window));
3572                 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3573         }
3574
3575 }
3576
3577 void
3578 modest_ui_actions_on_mark_as_read (GtkAction *action,
3579                                    ModestWindow *window)
3580 {       
3581         g_return_if_fail (MODEST_IS_WINDOW(window));
3582                 
3583         /* Mark each header as read */
3584         do_headers_action (window, headers_action_mark_as_read, NULL);
3585 }
3586
3587 void
3588 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3589                                      ModestWindow *window)
3590 {       
3591         g_return_if_fail (MODEST_IS_WINDOW(window));
3592                 
3593         /* Mark each header as read */
3594         do_headers_action (window, headers_action_mark_as_unread, NULL);
3595 }
3596
3597 void
3598 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3599                                   GtkRadioAction *selected,
3600                                   ModestWindow *window)
3601 {
3602         gint value;
3603
3604         value = gtk_radio_action_get_current_value (selected);
3605         if (MODEST_IS_WINDOW (window)) {
3606                 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3607         }
3608 }
3609
3610 void
3611 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3612                                                GtkRadioAction *selected,
3613                                                ModestWindow *window)
3614 {
3615         TnyHeaderFlags flags;
3616         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3617
3618         flags = gtk_radio_action_get_current_value (selected);
3619         modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3620 }
3621
3622 void
3623 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3624                                                   GtkRadioAction *selected,
3625                                                   ModestWindow *window)
3626 {
3627         gint file_format;
3628
3629         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3630
3631         file_format = gtk_radio_action_get_current_value (selected);
3632         modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3633 }
3634
3635
3636 void
3637 modest_ui_actions_on_zoom_plus (GtkAction *action,
3638                                 ModestWindow *window)
3639 {
3640         g_return_if_fail (MODEST_IS_WINDOW (window));
3641
3642         modest_window_zoom_plus (MODEST_WINDOW (window));
3643 }
3644
3645 void     
3646 modest_ui_actions_on_zoom_minus (GtkAction *action,
3647                                  ModestWindow *window)
3648 {
3649         g_return_if_fail (MODEST_IS_WINDOW (window));
3650
3651         modest_window_zoom_minus (MODEST_WINDOW (window));
3652 }
3653
3654 void     
3655 modest_ui_actions_on_toggle_fullscreen    (GtkToggleAction *toggle,
3656                                            ModestWindow *window)
3657 {
3658         ModestWindowMgr *mgr;
3659         gboolean fullscreen, active;
3660         g_return_if_fail (MODEST_IS_WINDOW (window));
3661
3662         mgr = modest_runtime_get_window_mgr ();
3663
3664         active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3665         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3666
3667         if (active != fullscreen) {
3668                 modest_window_mgr_set_fullscreen_mode (mgr, active);
3669                 gtk_window_present (GTK_WINDOW (window));
3670         }
3671 }
3672
3673 void
3674 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3675                                         ModestWindow *window)
3676 {
3677         ModestWindowMgr *mgr;
3678         gboolean fullscreen;
3679
3680         g_return_if_fail (MODEST_IS_WINDOW (window));
3681
3682         mgr = modest_runtime_get_window_mgr ();
3683         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3684         modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3685
3686         gtk_window_present (GTK_WINDOW (window));
3687 }
3688
3689 /* 
3690  * Used by modest_ui_actions_on_details to call do_headers_action 
3691  */
3692 static void
3693 headers_action_show_details (TnyHeader *header, 
3694                              ModestWindow *window,
3695                              gpointer user_data)
3696
3697 {
3698         GtkWidget *dialog;
3699         
3700         /* Create dialog */
3701         dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3702
3703         /* Run dialog */
3704         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3705         gtk_widget_show_all (dialog);
3706         gtk_dialog_run (GTK_DIALOG (dialog));
3707
3708         gtk_widget_destroy (dialog);
3709 }
3710
3711 /*
3712  * Show the folder details in a ModestDetailsDialog widget
3713  */
3714 static void
3715 show_folder_details (TnyFolder *folder, 
3716                      GtkWindow *window)
3717 {
3718         GtkWidget *dialog;
3719         
3720         /* Create dialog */
3721         dialog = modest_details_dialog_new_with_folder (window, folder);
3722
3723         /* Run dialog */
3724         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3725         gtk_widget_show_all (dialog);
3726         gtk_dialog_run (GTK_DIALOG (dialog));
3727
3728         gtk_widget_destroy (dialog);
3729 }
3730
3731 /*
3732  * Show the header details in a ModestDetailsDialog widget
3733  */
3734 void     
3735 modest_ui_actions_on_details (GtkAction *action, 
3736                               ModestWindow *win)
3737 {
3738         TnyList * headers_list;
3739         TnyIterator *iter;
3740         TnyHeader *header;              
3741
3742         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3743                 TnyMsg *msg;
3744
3745                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3746                 if (!msg)
3747                         return;
3748                 g_object_unref (msg);           
3749
3750                 headers_list = get_selected_headers (win);
3751                 if (!headers_list)
3752                         return;
3753
3754                 iter = tny_list_create_iterator (headers_list);
3755
3756                 header = TNY_HEADER (tny_iterator_get_current (iter));
3757                 if (header) {
3758                         headers_action_show_details (header, win, NULL);
3759                         g_object_unref (header);
3760                 }
3761
3762                 g_object_unref (iter);
3763                 g_object_unref (headers_list);
3764
3765         } else if (MODEST_IS_MAIN_WINDOW (win)) {
3766                 GtkWidget *folder_view, *header_view;
3767
3768                 /* Check which widget has the focus */
3769                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3770                                                                     MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3771                 if (gtk_widget_is_focus (folder_view)) {
3772                         TnyFolderStore *folder_store
3773                                 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3774                         if (!folder_store) {
3775                                 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3776                                 return; 
3777                         }
3778                         /* Show only when it's a folder */
3779                         /* This function should not be called for account items, 
3780                          * because we dim the menu item for them. */
3781                         if (TNY_IS_FOLDER (folder_store)) {
3782                                 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3783                         }
3784
3785                         g_object_unref (folder_store);
3786
3787                 } else {
3788                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3789                                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3790                         /* Show details of each header */
3791                         do_headers_action (win, headers_action_show_details, header_view);
3792                 }
3793         }
3794 }
3795
3796 void     
3797 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3798                                      ModestMsgEditWindow *window)
3799 {
3800         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3801
3802         modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3803 }
3804
3805 void     
3806 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3807                                       ModestMsgEditWindow *window)
3808 {
3809         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3810
3811         modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3812 }
3813
3814 void
3815 modest_ui_actions_toggle_folders_view (GtkAction *action, 
3816                                        ModestMainWindow *main_window)
3817 {
3818         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3819
3820         if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3821                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3822         else
3823                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3824 }
3825
3826 void 
3827 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle, 
3828                                      ModestWindow *window)
3829 {
3830         gboolean active, fullscreen = FALSE;
3831         ModestWindowMgr *mgr;
3832
3833         active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3834
3835         /* Check if we want to toggle the toolbar vuew in fullscreen
3836            or normal mode */
3837         if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)), 
3838                      "ViewShowToolbarFullScreen")) {
3839                 fullscreen = TRUE;
3840         }
3841
3842         /* Toggle toolbar */
3843         mgr = modest_runtime_get_window_mgr ();
3844         modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3845 }
3846
3847 void     
3848 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3849                                            ModestMsgEditWindow *window)
3850 {
3851         modest_msg_edit_window_select_font (window);
3852 }
3853
3854
3855 void
3856 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3857                                                   const gchar *display_name,
3858                                                   GtkWindow *window)
3859 {
3860         /* don't update the display name if it was already set;
3861          * updating the display name apparently is expensive */
3862         const gchar* old_name = gtk_window_get_title (window);
3863
3864         if (display_name == NULL)
3865                 display_name = " ";
3866
3867         if (old_name && display_name && strcmp (old_name, display_name) == 0)
3868                 return; /* don't do anything */
3869
3870         /* This is usually used to change the title of the main window, which
3871          * is the one that holds the folder view. Note that this change can
3872          * happen even when the widget doesn't have the focus. */
3873         gtk_window_set_title (window, display_name);
3874
3875 }
3876
3877 void
3878 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3879 {
3880         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3881         modest_msg_edit_window_select_contacts (window);
3882 }
3883
3884 void
3885 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3886 {
3887         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3888         modest_msg_edit_window_check_names (window, FALSE);
3889 }
3890
3891 static void
3892 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3893 {
3894         modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3895                                          GTK_WIDGET (user_data));
3896 }
3897
3898 /*
3899  * This function is used to track changes in the selection of the
3900  * folder view that is inside the "move to" dialog to enable/disable
3901  * the OK button because we do not want the user to select a disallowed
3902  * destination for a folder.
3903  * The user also not desired to be able to use NEW button on items where
3904  * folder creation is not possibel.
3905  */
3906 static void
3907 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3908                                             TnyFolderStore *folder_store,
3909                                             gboolean selected,
3910                                             gpointer user_data)
3911 {
3912         GtkWidget *dialog = NULL;
3913         GtkWidget *ok_button = NULL, *new_button = NULL;
3914         GList *children = NULL;
3915         gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3916         gboolean moving_folder = FALSE;
3917         gboolean is_local_account = TRUE;
3918         GtkWidget *folder_view = NULL;
3919         ModestTnyFolderRules rules;
3920
3921         if (!selected)
3922                 return;
3923
3924         /* Get the OK button */
3925         dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3926         if (!dialog)
3927                 return;
3928
3929         children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3930         ok_button = GTK_WIDGET (children->next->next->data);
3931         new_button = GTK_WIDGET (children->next->data);
3932         g_list_free (children);
3933
3934         /* check if folder_store is an remote account */
3935         if (TNY_IS_ACCOUNT (folder_store)) {
3936                 TnyAccount *local_account = NULL;
3937                 TnyAccount *mmc_account = NULL;
3938                 ModestTnyAccountStore *account_store = NULL;
3939
3940                 account_store = modest_runtime_get_account_store ();
3941                 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3942                 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
3943
3944                 if ((gpointer) local_account != (gpointer) folder_store &&
3945                     (gpointer) mmc_account != (gpointer) folder_store) {
3946                         const char *proto_name = tny_account_get_proto (TNY_ACCOUNT (folder_store));
3947                         ModestTransportStoreProtocol proto = MODEST_PROTOCOL_STORE_MAILDIR;
3948                         if (proto_name != NULL) {
3949                                 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
3950                         }
3951                         is_local_account = FALSE;
3952                         /* New button should be dimmed on remote
3953                            POP account root */
3954                         new_sensitive = (proto != MODEST_PROTOCOL_STORE_POP);
3955                 }
3956                 g_object_unref (local_account);
3957         }
3958
3959         /* Check the target folder rules */
3960         if (TNY_IS_FOLDER (folder_store)) {
3961                 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3962                 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3963                         ok_sensitive = FALSE;
3964                         new_sensitive = FALSE;
3965                         goto end;
3966                 }
3967         }
3968
3969         /* Check if we're moving a folder */
3970         if (MODEST_IS_MAIN_WINDOW (user_data)) {
3971                 /* Get the widgets */
3972                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3973                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3974                 if (gtk_widget_is_focus (folder_view))
3975                         moving_folder = TRUE;
3976         }
3977
3978         if (moving_folder) {
3979                 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3980
3981                 /* Get the folder to move */
3982                 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3983                 
3984                 /* Check that we're not moving to the same folder */
3985                 if (TNY_IS_FOLDER (moved_folder)) {
3986                         parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3987                         if (parent == folder_store)
3988                                 ok_sensitive = FALSE;
3989                         g_object_unref (parent);
3990                 } 
3991
3992                 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3993                         /* Do not allow to move to an account unless it's the
3994                            local folders account */
3995                         if (!is_local_account)
3996                                 ok_sensitive = FALSE;
3997                 } 
3998
3999                 if (ok_sensitive && (moved_folder == folder_store)) {
4000                         /* Do not allow to move to itself */
4001                         ok_sensitive = FALSE;
4002                 }
4003                 g_object_unref (moved_folder);
4004         } else {
4005                 TnyHeader *header = NULL;
4006                 TnyFolder *src_folder = NULL;
4007
4008                 /* Moving a message */
4009                 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4010                         header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
4011                         src_folder = tny_header_get_folder (header);
4012                         g_object_unref (header);
4013                 } else {
4014                         src_folder = 
4015                                 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
4016                 }
4017
4018                 /* Do not allow to move the msg to the same folder */
4019                 /* Do not allow to move the msg to an account */
4020                 if ((gpointer) src_folder == (gpointer) folder_store ||
4021                     TNY_IS_ACCOUNT (folder_store))
4022                         ok_sensitive = FALSE;
4023                 g_object_unref (src_folder);
4024         }
4025
4026  end:
4027         /* Set sensitivity of the OK button */
4028         gtk_widget_set_sensitive (ok_button, ok_sensitive);
4029         /* Set sensitivity of the NEW button */
4030         gtk_widget_set_sensitive (new_button, new_sensitive);
4031 }
4032
4033
4034 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4035
4036 static GtkWidget*
4037 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4038 {
4039         return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4040                                              MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4041 }
4042
4043 static GtkWidget*
4044 create_move_to_dialog (GtkWindow *win,
4045                        GtkWidget *folder_view,
4046                        GtkWidget **tree_view)
4047 {
4048         GtkWidget *dialog, *scroll;
4049         GtkWidget *new_button;
4050
4051         dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4052                                               GTK_WINDOW (win),
4053                                               GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4054                                               NULL);
4055
4056         gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4057         /* We do this manually so GTK+ does not associate a response ID for
4058          * the button. */
4059         new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4060         gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4061         gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4062
4063         /* Create scrolled window */
4064         scroll = gtk_scrolled_window_new (NULL, NULL);
4065         gtk_scrolled_window_set_policy  (GTK_SCROLLED_WINDOW (scroll),
4066                                          GTK_POLICY_AUTOMATIC,
4067                                          GTK_POLICY_AUTOMATIC);
4068
4069         /* Create folder view */
4070         *tree_view = modest_platform_create_folder_view (NULL);
4071
4072         /* Track changes in the selection to
4073          * disable the OK button whenever "Move to" is not possible
4074          * disbale NEW button whenever New is not possible */
4075         g_signal_connect (*tree_view,
4076                           "folder_selection_changed",
4077                           G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4078                           win);
4079
4080         /* Listen to clicks on New button */
4081         g_signal_connect (G_OBJECT (new_button), 
4082                           "clicked", 
4083                           G_CALLBACK(create_move_to_dialog_on_new_folder), 
4084                           *tree_view);
4085
4086         /* It could happen that we're trying to move a message from a
4087            window (msg window for example) after the main window was
4088            closed, so we can not just get the model of the folder
4089            view */
4090         if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4091                 const gchar *visible_id = NULL;
4092
4093                 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4094                                               MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4095                 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view), 
4096                                                MODEST_FOLDER_VIEW(*tree_view));
4097
4098                 visible_id = 
4099                         modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4100
4101                 /* Show the same account than the one that is shown in the main window */
4102                 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view), 
4103                                                                              visible_id);
4104         } else {
4105                 const gchar *active_account_name = NULL;
4106                 ModestAccountMgr *mgr = NULL;
4107                 ModestAccountSettings *settings = NULL;
4108                 ModestServerAccountSettings *store_settings = NULL;
4109
4110                 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4111                                               MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4112                 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view), 
4113                                                  TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4114
4115                 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4116                 mgr = modest_runtime_get_account_mgr ();
4117                 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4118
4119                 if (settings) {
4120                         const gchar *store_account_name;
4121                         store_settings = modest_account_settings_get_store_settings (settings);
4122                         store_account_name = modest_server_account_settings_get_account_name (store_settings);
4123
4124                         modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4125                                                                                      store_account_name);
4126                         g_object_unref (store_settings);
4127                         g_object_unref (settings);
4128                 }
4129         }
4130
4131         /* we keep a pointer to the embedded folder view, so we can retrieve it with
4132          *   get_folder_view_from_move_to_dialog 
4133          * (see above) later (needed for focus handling) 
4134          */
4135         g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4136
4137         
4138         /* Hide special folders */
4139         modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4140
4141         gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4142
4143         /* Add scroll to dialog */
4144         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), 
4145                             scroll, TRUE, TRUE, 0);
4146
4147         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4148         gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4149
4150         return dialog;
4151 }
4152
4153 /*
4154  * Returns TRUE if at least one of the headers of the list belongs to
4155  * a message that has been fully retrieved.
4156  */
4157 #if 0 /* no longer in use. delete in 2007.10 */
4158 static gboolean
4159 has_retrieved_msgs (TnyList *list)
4160 {
4161         TnyIterator *iter;
4162         gboolean found = FALSE;
4163
4164         iter = tny_list_create_iterator (list);
4165         while (!tny_iterator_is_done (iter) && !found) {
4166                 TnyHeader *header;
4167                 TnyHeaderFlags flags = 0;
4168
4169                 header = TNY_HEADER (tny_iterator_get_current (iter));
4170                 if (header) {
4171                         flags = tny_header_get_flags (header);
4172                         if (flags & TNY_HEADER_FLAG_CACHED)
4173 /*                      if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
4174                                 found = TRUE;
4175
4176                         g_object_unref (header);
4177                 }
4178
4179                 if (!found)
4180                         tny_iterator_next (iter);
4181         }
4182         g_object_unref (iter);
4183
4184         return found;
4185 }
4186 #endif /* 0 */
4187
4188
4189 /*
4190  * Shows a confirmation dialog to the user when we're moving messages
4191  * from a remote server to the local storage. Returns the dialog
4192  * response. If it's other kind of movement then it always returns
4193  * GTK_RESPONSE_OK
4194  *
4195  * This one is used by the next functions:
4196  *      modest_ui_actions_on_paste                      - commented out
4197  *      drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4198  */
4199 gint
4200 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4201                                              TnyFolder *dest_folder,
4202                                              gboolean delete,
4203                                              TnyList *headers)
4204 {
4205         gint response = GTK_RESPONSE_OK;
4206         TnyAccount *account = NULL;
4207         TnyFolder *src_folder = NULL;
4208         TnyIterator *iter = NULL;
4209         TnyHeader *header = NULL;
4210
4211         /* return with OK if the destination is a remote folder */
4212         if (modest_tny_folder_is_remote_folder (dest_folder))
4213                 return GTK_RESPONSE_OK;
4214
4215         /* Get source folder */
4216         iter = tny_list_create_iterator (headers);
4217         header = TNY_HEADER (tny_iterator_get_current (iter));
4218         if (header) {
4219                 src_folder = tny_header_get_folder (header);
4220                 g_object_unref (header);
4221         }
4222         g_object_unref (iter);
4223
4224         /* if no src_folder, message may be an attahcment */
4225         if (src_folder == NULL) 
4226                 return GTK_RESPONSE_CANCEL;
4227
4228         /* If the source is a local or MMC folder */
4229         if (!modest_tny_folder_is_remote_folder (src_folder)) {
4230                 g_object_unref (src_folder);
4231                 return GTK_RESPONSE_OK;
4232         }
4233
4234         /* Get the account */
4235         account = tny_folder_get_account (src_folder);
4236
4237         /* now if offline we ask the user */
4238         if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4239                 response = GTK_RESPONSE_OK;
4240         else
4241                 response = GTK_RESPONSE_CANCEL;
4242
4243         /* Frees */
4244         g_object_unref (src_folder);
4245         g_object_unref (account);
4246
4247         return response;
4248 }
4249
4250 static void
4251 move_to_cb (ModestMailOperation *mail_op, 
4252             gpointer user_data)
4253 {
4254         MoveToHelper *helper = (MoveToHelper *) user_data;
4255
4256         /* Note that the operation could have failed, in that case do
4257            nothing */
4258         if (modest_mail_operation_get_status (mail_op) == 
4259             MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4260
4261                 GObject *object = modest_mail_operation_get_source (mail_op);
4262                 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4263                         ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4264
4265                         if (modest_msg_view_window_last_message_selected (self) &&
4266                             modest_msg_view_window_first_message_selected (self)) {
4267                                 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (self));
4268                         } else if (!modest_msg_view_window_select_next_message (self) &&
4269                                    !modest_msg_view_window_select_previous_message (self)) {
4270                                 /* No more messages to view, so close this window */
4271                                 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4272                         }
4273                 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
4274                         GtkWidget *header_view;
4275                         GtkTreePath *path;
4276                         GtkTreeSelection *sel;
4277
4278                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4279                                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4280                         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4281                         path = gtk_tree_row_reference_get_path (helper->reference);
4282                         gtk_tree_selection_select_path (sel, path);
4283                         gtk_tree_path_free (path);
4284                 }
4285                 g_object_unref (object);
4286         }
4287
4288         /* Close the "Pasting" information banner */
4289         gtk_widget_destroy (GTK_WIDGET(helper->banner));
4290         if (helper->reference != NULL)
4291                 gtk_tree_row_reference_free (helper->reference);
4292         g_free (helper);
4293 }
4294
4295 static void
4296 folder_move_to_cb (ModestMailOperation *mail_op, 
4297                    TnyFolder *new_folder,
4298                    gpointer user_data)
4299 {
4300         move_to_cb (mail_op, user_data);
4301 }
4302
4303 static void
4304 msgs_move_to_cb (ModestMailOperation *mail_op, 
4305                  gpointer user_data)
4306 {
4307         move_to_cb (mail_op, user_data);
4308 }
4309
4310 void
4311 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op, 
4312                                              gpointer user_data)
4313 {
4314         ModestWindow *main_window = NULL;
4315         GObject *win = NULL;
4316         
4317         /* Disable next automatic folder selection */
4318         main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4319                                                          FALSE); /* don't create */
4320         if (main_window) {
4321                 GtkWidget *folder_view = NULL;
4322         
4323                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4324                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW); 
4325                 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4326                 
4327                 if (user_data && TNY_IS_FOLDER (user_data)) {
4328                         modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), 
4329                                                           TNY_FOLDER (user_data), FALSE);
4330                 }
4331         }
4332
4333         /* Show notification dialog */
4334         win = modest_mail_operation_get_source (mail_op);
4335         modest_platform_run_information_dialog ((GtkWindow *) win, _("mail_in_ui_folder_move_target_error"));
4336         if (win)
4337                 g_object_unref (win);
4338 }
4339
4340 void
4341 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op, 
4342                                               gpointer user_data)
4343 {
4344         GObject *win = modest_mail_operation_get_source (mail_op);
4345         const GError *error = modest_mail_operation_get_error (mail_op);
4346
4347         g_return_if_fail (error != NULL);
4348         if (error->message != NULL)             
4349                 g_printerr ("modest: %s\n", error->message);
4350         else
4351                 g_printerr ("modest: unkonw error on send&receive operation");
4352
4353         /* Show error message */
4354 /*      if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
4355 /*              modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4356 /*                                                      _CS("sfil_ib_unable_to_receive")); */
4357 /*      else  */
4358 /*              modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4359 /*                                                      _CS("sfil_ib_unable_to_send")); */
4360         g_object_unref (win);
4361 }
4362
4363 static void
4364 open_msg_for_purge_cb (ModestMailOperation *mail_op, 
4365                        TnyHeader *header, 
4366                        gboolean canceled,
4367                        TnyMsg *msg, 
4368                        GError *err,
4369                        gpointer user_data)
4370 {
4371         TnyList *parts;
4372         TnyIterator *iter;
4373         gint pending_purges = 0;
4374         gboolean some_purged = FALSE;
4375         ModestWindow *win = MODEST_WINDOW (user_data);
4376         ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4377
4378         /* If there was any error */
4379         if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4380                 modest_window_mgr_unregister_header (mgr, header);
4381                 return;
4382         }
4383
4384         /* Once the message has been retrieved for purging, we check if
4385          * it's all ok for purging */
4386
4387         parts = tny_simple_list_new ();
4388         tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4389         iter = tny_list_create_iterator (parts);
4390
4391         while (!tny_iterator_is_done (iter)) {
4392                 TnyMimePart *part;
4393                 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4394                 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4395                         if (tny_mime_part_is_purged (part))
4396                                 some_purged = TRUE;
4397                         else
4398                                 pending_purges++;
4399                 }
4400
4401                 if (part)
4402                         g_object_unref (part);
4403
4404                 tny_iterator_next (iter);
4405         }
4406         g_object_unref (iter);
4407         
4408
4409         if (pending_purges>0) {
4410                 gint response;
4411                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4412
4413                 if (response == GTK_RESPONSE_OK) {
4414                         modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4415                         iter = tny_list_create_iterator (parts);
4416                         while (!tny_iterator_is_done (iter)) {
4417                                 TnyMimePart *part;
4418                                 
4419                                 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4420                                 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4421                                         tny_mime_part_set_purged (part);
4422
4423                                 if (part)
4424                                         g_object_unref (part);
4425
4426                                 tny_iterator_next (iter);
4427                         }
4428                         
4429                         tny_msg_rewrite_cache (msg);
4430                 }
4431      /* } else { */
4432                 /* This string no longer exists, refer to NB#75415 for more info */
4433                 /* modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged")); */
4434         }
4435         g_object_unref (iter);
4436
4437         modest_window_mgr_unregister_header (mgr, header);
4438
4439         g_object_unref (parts);
4440 }
4441
4442 static void
4443 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4444                                                      ModestMainWindow *win)
4445 {
4446         GtkWidget *header_view;
4447         TnyList *header_list;
4448         TnyIterator *iter;
4449         TnyHeader *header;
4450         TnyHeaderFlags flags;
4451         ModestWindow *msg_view_window =  NULL;
4452         gboolean found;
4453
4454         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4455
4456         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4457                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4458
4459         header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4460         if (!header_list) {
4461                 g_warning ("%s: no header selected", __FUNCTION__);
4462                 return;
4463         }
4464         
4465         if (tny_list_get_length (header_list) == 1) {
4466                 iter = tny_list_create_iterator (header_list);
4467                 header = TNY_HEADER (tny_iterator_get_current (iter));
4468                 g_object_unref (iter);
4469         } else
4470                 return;
4471         
4472         if (!header || !TNY_IS_HEADER(header)) {
4473                 g_warning ("%s: header is not valid", __FUNCTION__);
4474                 return;
4475         }
4476         
4477         found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4478                                                           header, &msg_view_window);
4479         flags = tny_header_get_flags (header);
4480         if (!(flags & TNY_HEADER_FLAG_CACHED))
4481                 return;
4482         if (found) {
4483                 if (msg_view_window != NULL) 
4484                         modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4485                 else {
4486                         /* do nothing; uid was registered before, so window is probably on it's way */
4487                         g_warning ("debug: header %p has already been registered", header);
4488                 }
4489         } else {
4490                 ModestMailOperation *mail_op = NULL;
4491                 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
4492                 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
4493                                                                          modest_ui_actions_get_msgs_full_error_handler,
4494                                                                          NULL, NULL);
4495                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4496                 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4497                 
4498                 g_object_unref (mail_op);
4499         }
4500         if (header)
4501                 g_object_unref (header);
4502         if (header_list)
4503                 g_object_unref (header_list);
4504 }
4505
4506 /**
4507  * Utility function that transfer messages from both the main window
4508  * and the msg view window when using the "Move to" dialog
4509  */
4510 static void
4511 xfer_messages_from_move_to_cb  (gboolean canceled, GError *err,
4512                                 GtkWindow *parent_window, 
4513                                 TnyAccount *account, gpointer user_data)
4514 {
4515         TnyFolderStore *dst_folder = TNY_FOLDER_STORE (user_data);
4516         ModestWindow *win = MODEST_WINDOW (parent_window);
4517         TnyList *headers = NULL;
4518         TnyAccount *dst_account = NULL;
4519         const gchar *proto_str = NULL;
4520         gboolean dst_is_pop = FALSE;
4521
4522         if (canceled || err) {
4523                 g_object_unref (dst_folder);
4524                 return;
4525         }
4526
4527         dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4528         proto_str = tny_account_get_proto (dst_account);
4529
4530         /* tinymail will return NULL for local folders it seems */
4531         dst_is_pop = proto_str &&
4532                 (modest_protocol_info_get_transport_store_protocol (proto_str) == 
4533                  MODEST_PROTOCOL_STORE_POP);
4534
4535         g_object_unref (dst_account);
4536
4537         /* Get selected headers */
4538         headers = get_selected_headers (MODEST_WINDOW (win));
4539         if (!headers) {
4540                 g_warning ("%s: no headers selected", __FUNCTION__);
4541                 return;
4542         }
4543
4544
4545         if (dst_is_pop) {
4546                 modest_platform_information_banner (GTK_WIDGET (win),
4547                                                     NULL,
4548                                                     ngettext("mail_in_ui_folder_move_target_error",
4549                                                              "mail_in_ui_folder_move_targets_error",
4550                                                              tny_list_get_length (headers)));
4551                 g_object_unref (headers);
4552                 return;
4553         }
4554
4555         MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4556         helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4557                                                            _CS("ckct_nw_pasting"));
4558         if (helper->banner != NULL)  {
4559                 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4560                 gtk_widget_show (GTK_WIDGET(helper->banner));
4561         }
4562
4563         if (MODEST_IS_MAIN_WINDOW (win)) {
4564                 GtkWidget *header_view = 
4565                         modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
4566                                                              MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4567                 helper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
4568         }
4569
4570         ModestMailOperation *mail_op = 
4571                 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4572                                                                modest_ui_actions_move_folder_error_handler,
4573                                                                NULL, NULL);
4574         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
4575                                          mail_op);
4576
4577         modest_mail_operation_xfer_msgs (mail_op, 
4578                                          headers,
4579                                          TNY_FOLDER (dst_folder),
4580                                          TRUE,
4581                                          msgs_move_to_cb,
4582                                          helper);
4583
4584         g_object_unref (G_OBJECT (mail_op));
4585         g_object_unref (headers);
4586         g_object_unref (dst_folder);
4587 }
4588
4589 typedef struct {
4590         TnyAccount *dst_account;
4591         ModestConnectedPerformer callback;
4592         gpointer data;
4593 } DoubleConnectionInfo;
4594
4595 static void
4596 src_account_connect_performer (gboolean canceled, 
4597                                GError *err,
4598                                GtkWindow *parent_window, 
4599                                TnyAccount *src_account, 
4600                                gpointer user_data)
4601 {
4602         DoubleConnectionInfo *info = (DoubleConnectionInfo *) user_data;
4603
4604         if (canceled || err) {
4605                 /* If there was any error call the user callback */
4606                 info->callback (canceled, err, parent_window, src_account, info->data);
4607         } else {
4608                 /* Connect the destination account */
4609                 modest_platform_connect_if_remote_and_perform (parent_window, TRUE, 
4610                                                                TNY_FOLDER_STORE (info->dst_account),
4611                                                                info->callback, info->data);
4612         }
4613
4614         /* Free the info object */
4615         g_object_unref (info->dst_account);
4616         g_slice_free (DoubleConnectionInfo, info);
4617 }
4618
4619 typedef struct {
4620         TnyFolder *src_folder;
4621         TnyFolderStore *dst_folder;
4622         gboolean delete_original;
4623         GtkWidget *folder_view;
4624 } MoveFolderInfo;
4625
4626 static void
4627 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window, 
4628                 TnyAccount *account, gpointer user_data)
4629 {
4630         MoveFolderInfo *info = (MoveFolderInfo*)user_data;
4631         GtkTreeSelection *sel;
4632         ModestMailOperation *mail_op = NULL;
4633         
4634         if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
4635                 g_object_unref (G_OBJECT (info->src_folder));
4636                 g_object_unref (G_OBJECT (info->dst_folder));
4637                 g_free (info);
4638                 return;
4639         }
4640         
4641         MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4642         helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
4643                         _CS("ckct_nw_pasting"));
4644         if (helper->banner != NULL)  {
4645                 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4646                 gtk_widget_show (GTK_WIDGET(helper->banner));
4647         }
4648         /* Clean folder on header view before moving it */
4649         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
4650         gtk_tree_selection_unselect_all (sel);
4651
4652         /* Let gtk events run. We need that the folder
4653            view frees its reference to the source
4654            folder *before* issuing the mail operation
4655            so we need the signal handler of selection
4656            changed to happen before the mail
4657            operation 
4658         while (gtk_events_pending ())
4659                 gtk_main_iteration ();   */
4660
4661         mail_op =
4662                 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4663                                 modest_ui_actions_move_folder_error_handler,
4664                                 info->src_folder, NULL);
4665         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4666                         mail_op);
4667
4668         /* Select *after* the changes */
4669         /* TODO: this function hangs UI after transfer */ 
4670         /*                      modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4671         /*                                                        TNY_FOLDER (src_folder), TRUE); */
4672
4673         modest_mail_operation_xfer_folder (mail_op,
4674                         TNY_FOLDER (info->src_folder),
4675                         info->dst_folder,
4676                         info->delete_original, 
4677                         folder_move_to_cb, 
4678                         helper);
4679
4680         if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {       
4681                 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
4682                                                   TNY_FOLDER (info->dst_folder), TRUE);
4683         }
4684         
4685         /* Unref mail operation */
4686         g_object_unref (G_OBJECT (mail_op));
4687         g_object_unref (G_OBJECT (info->src_folder));
4688         g_object_unref (G_OBJECT (info->dst_folder));
4689         g_free (user_data);
4690 }
4691
4692 /*
4693  * UI handler for the "Move to" action when invoked from the
4694  * ModestMainWindow
4695  */
4696 static void 
4697 modest_ui_actions_on_main_window_move_to (GtkAction *action, 
4698                                           GtkWidget *folder_view,
4699                                           TnyFolderStore *dst_folder,
4700                                           ModestMainWindow *win)
4701 {
4702         ModestHeaderView *header_view = NULL;
4703         TnyFolderStore *src_folder;
4704         gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4705
4706         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4707
4708         /* Get the source folder */
4709         src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4710
4711         /* Get header view */
4712         header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4713
4714         /* Get folder or messages to transfer */
4715         if (gtk_widget_is_focus (folder_view)) {
4716                 gboolean do_xfer = TRUE;
4717
4718                 /* Allow only to transfer folders to the local root folder */
4719                 if (TNY_IS_ACCOUNT (dst_folder) && 
4720                     !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4721                         do_xfer = FALSE;
4722                 } else if (!TNY_IS_FOLDER (src_folder)) {
4723                         g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4724                         do_xfer = FALSE;
4725                 } /* else if (!online && modest_tny_folder_store_is_remote(src_folder)) {
4726                         guint num_headers = tny_folder_get_all_count(TNY_FOLDER (src_folder));
4727                         TnyAccount *account = tny_folder_get_account (TNY_FOLDER (src_folder));
4728                         if (!connect_to_get_msg(MODEST_WINDOW (win), num_headers, account))
4729                                 do_xfer = FALSE;
4730                         g_object_unref (account);
4731                 }*/
4732
4733                 if (do_xfer) {
4734                         MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
4735                         info->src_folder = TNY_FOLDER (src_folder);
4736                         info->dst_folder = dst_folder;
4737                         info->delete_original = TRUE;
4738                         info->folder_view = folder_view;
4739                         g_object_ref (G_OBJECT (info->src_folder));
4740                         g_object_ref (G_OBJECT (info->dst_folder));
4741                         modest_platform_connect_if_remote_and_perform(GTK_WINDOW (win), TRUE,
4742                                     TNY_FOLDER_STORE (dst_folder), on_move_folder_cb, info);
4743                 }
4744         } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4745                 gboolean do_xfer = TRUE;
4746
4747                 /* Show an error when trying to move msgs to an account */      
4748                 if (!TNY_IS_FOLDER (dst_folder)) {
4749                         modest_platform_information_banner (GTK_WIDGET (win),
4750                                                             NULL,
4751                                                             _CS("ckdg_ib_unable_to_move_to_current_location"));
4752                         goto free;
4753                 }
4754
4755                 /* Ask for confirmation if the source folder is remote and we're not connected */
4756                 if (!online && modest_tny_folder_store_is_remote(src_folder)) {
4757                         TnyList *headers = modest_header_view_get_selected_headers(header_view);
4758                         if (!msgs_already_deleted_from_server(headers, src_folder)) {
4759                                 guint num_headers = tny_list_get_length(headers);
4760                                 TnyAccount *account = get_account_from_header_list (headers);
4761                                 GtkResponseType response;
4762
4763                                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
4764                                                                                     ngettext("mcen_nc_get_msg",
4765                                                                                              "mcen_nc_get_msgs",
4766                                                                                              num_headers));
4767                                 if (response == GTK_RESPONSE_CANCEL)
4768                                         do_xfer = FALSE;
4769                                 
4770                                 g_object_unref (account);
4771                         }
4772                         g_object_unref(headers);
4773                 }
4774                 if (do_xfer) /* Transfer messages */ {
4775                         DoubleConnectionInfo *info = g_slice_new (DoubleConnectionInfo);
4776                         info->callback = xfer_messages_from_move_to_cb;
4777                         info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4778                         info->data = g_object_ref (dst_folder);
4779
4780                         modest_platform_connect_if_remote_and_perform(GTK_WINDOW (win), TRUE,
4781                                                                       TNY_FOLDER_STORE (src_folder), 
4782                                                                       src_account_connect_performer, 
4783                                                                       info);
4784                 }
4785         }
4786
4787  free:
4788         if (src_folder)
4789                 g_object_unref (src_folder);
4790 }
4791
4792
4793 /*
4794  * UI handler for the "Move to" action when invoked from the
4795  * ModestMsgViewWindow
4796  */
4797 static void 
4798 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action, 
4799                                               TnyFolderStore *dst_folder,
4800                                               ModestMsgViewWindow *win)
4801 {
4802         TnyHeader *header = NULL;
4803         TnyFolder *src_folder = NULL;
4804         TnyAccount *account = NULL;
4805         gboolean do_xfer = FALSE;
4806
4807         /* Create header list */
4808         header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));              
4809         src_folder = TNY_FOLDER (tny_header_get_folder(header));
4810         g_object_unref (header);
4811
4812         account = tny_folder_get_account (src_folder);
4813         if (!modest_tny_folder_store_is_remote(TNY_FOLDER_STORE(src_folder))) {
4814                 /* Transfer if the source folder is local */
4815                 do_xfer = TRUE;
4816         } else if (remote_folder_is_pop(TNY_FOLDER_STORE(src_folder))) {
4817                 /* Transfer if the source folder is POP (as it means
4818                  * that the message is already downloaded) */
4819                 do_xfer = TRUE;
4820         } else if (connect_to_get_msg(MODEST_WINDOW(win), 1, account)) {
4821                 /* Transfer after asking confirmation */
4822                 do_xfer = TRUE;
4823         }
4824
4825         if (do_xfer) {
4826                 g_object_ref (dst_folder);
4827                 modest_platform_connect_if_remote_and_perform(GTK_WINDOW (win), TRUE,
4828                                 TNY_FOLDER_STORE (dst_folder), xfer_messages_from_move_to_cb, dst_folder);
4829         }
4830         g_object_unref (account);
4831         g_object_unref (src_folder);
4832 }
4833
4834 void 
4835 modest_ui_actions_on_move_to (GtkAction *action, 
4836                               ModestWindow *win)
4837 {
4838         GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4839         gint result = 0;
4840         TnyFolderStore *dst_folder = NULL;
4841         ModestMainWindow *main_window;
4842
4843         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4844                           MODEST_IS_MSG_VIEW_WINDOW (win));
4845
4846         /* Get the main window if exists */
4847         if (MODEST_IS_MAIN_WINDOW (win))
4848                 main_window = MODEST_MAIN_WINDOW (win);
4849         else
4850                 main_window = 
4851                         MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4852                                                                                FALSE)); /* don't create */
4853
4854         /* Get the folder view widget if exists */
4855         if (main_window)
4856                 folder_view = modest_main_window_get_child_widget (main_window,
4857                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4858         else
4859                 folder_view = NULL;
4860
4861         /* Create and run the dialog */
4862         dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4863         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4864         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4865         result = gtk_dialog_run (GTK_DIALOG(dialog));
4866         g_object_ref (tree_view);
4867         gtk_widget_destroy (dialog);
4868
4869         if (result != GTK_RESPONSE_ACCEPT)
4870                 return;
4871
4872         dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4873         /* Do window specific stuff */
4874         if (MODEST_IS_MAIN_WINDOW (win)) {
4875                 modest_ui_actions_on_main_window_move_to (action,
4876                                 folder_view,
4877                                 dst_folder,
4878                                 MODEST_MAIN_WINDOW (win));
4879         } else {
4880                 modest_ui_actions_on_msg_view_window_move_to (action,
4881                                 dst_folder,
4882                                 MODEST_MSG_VIEW_WINDOW (win));
4883         }
4884
4885         if (dst_folder)
4886                 g_object_unref (dst_folder);
4887 }
4888
4889 /*
4890  * Calls #HeadersFunc for each header already selected in the main
4891  * window or the message currently being shown in the msg view window
4892  */
4893 static void
4894 do_headers_action (ModestWindow *win, 
4895                    HeadersFunc func,
4896                    gpointer user_data)
4897 {
4898         TnyList *headers_list = NULL;
4899         TnyIterator *iter = NULL;
4900         TnyHeader *header = NULL;
4901         TnyFolder *folder = NULL;
4902
4903         /* Get headers */
4904         headers_list = get_selected_headers (win);
4905         if (!headers_list)
4906                 return;
4907
4908         /* Get the folder */
4909         iter = tny_list_create_iterator (headers_list);
4910         header = TNY_HEADER (tny_iterator_get_current (iter));
4911         if (header) {
4912                 folder = tny_header_get_folder (header);
4913                 g_object_unref (header);
4914         }
4915
4916         /* Call the function for each header */
4917         while (!tny_iterator_is_done (iter)) {
4918                 header = TNY_HEADER (tny_iterator_get_current (iter));
4919                 func (header, win, user_data);
4920                 g_object_unref (header);
4921                 tny_iterator_next (iter);
4922         }
4923
4924         /* Trick: do a poke status in order to speed up the signaling
4925            of observers */
4926         tny_folder_poke_status (folder);
4927
4928         /* Frees */
4929         g_object_unref (folder);
4930         g_object_unref (iter);
4931         g_object_unref (headers_list);
4932 }
4933
4934 void 
4935 modest_ui_actions_view_attachment (GtkAction *action,
4936                                    ModestWindow *window)
4937 {
4938         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4939                 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4940         } else {
4941                 /* not supported window for this action */
4942                 g_return_if_reached ();
4943         }
4944 }
4945
4946 void
4947 modest_ui_actions_save_attachments (GtkAction *action,
4948                                     ModestWindow *window)
4949 {
4950         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4951                 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4952         } else {
4953                 /* not supported window for this action */
4954                 g_return_if_reached ();
4955         }
4956 }
4957
4958 void
4959 modest_ui_actions_remove_attachments (GtkAction *action,
4960                                       ModestWindow *window)
4961 {
4962         if (MODEST_IS_MAIN_WINDOW (window)) {
4963                 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4964         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4965                 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4966         } else {
4967                 /* not supported window for this action */
4968                 g_return_if_reached ();
4969         }
4970 }
4971
4972 void 
4973 modest_ui_actions_on_settings (GtkAction *action, 
4974                                ModestWindow *win)
4975 {
4976         GtkWidget *dialog;
4977
4978         dialog = modest_platform_get_global_settings_dialog ();
4979         gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4980         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4981         gtk_widget_show_all (dialog);
4982
4983         gtk_dialog_run (GTK_DIALOG (dialog));
4984
4985         gtk_widget_destroy (dialog);
4986 }
4987
4988 void 
4989 modest_ui_actions_on_help (GtkAction *action, 
4990                            GtkWindow *win)
4991 {
4992         const gchar *help_id;
4993
4994         g_return_if_fail (action);
4995         g_return_if_fail (win && GTK_IS_WINDOW(win));
4996         
4997         help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
4998         
4999         if (help_id)
5000                 modest_platform_show_help (GTK_WINDOW (win), help_id);
5001         else
5002                 g_warning ("%s: no help for window %p", __FUNCTION__, win);
5003 }
5004
5005 static void
5006 retrieve_msg_contents_performer (gboolean canceled, 
5007                                  GError *err,
5008                                  GtkWindow *parent_window, 
5009                                  TnyAccount *account, 
5010                                  gpointer user_data)
5011 {
5012         ModestMailOperation *mail_op;
5013         TnyList *headers = TNY_LIST (user_data);
5014
5015         if (err || canceled) {
5016                 goto out;
5017         }
5018
5019         /* Create mail operation */
5020         mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5021                                                                  modest_ui_actions_get_msgs_full_error_handler, 
5022                                                                  NULL, NULL);
5023         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5024         modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
5025
5026         /* Frees */
5027         g_object_unref (mail_op);
5028  out:
5029         g_object_unref (headers);
5030         g_object_unref (account);
5031 }
5032
5033 void 
5034 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5035                                             ModestWindow *window)
5036 {
5037         TnyList *headers = NULL;
5038         TnyAccount *account = NULL;
5039         TnyIterator *iter = NULL;
5040         TnyHeader *header = NULL;
5041         TnyFolder *folder = NULL;
5042
5043         /* Get headers */
5044         headers = get_selected_headers (window);
5045         if (!headers)
5046                 return;
5047
5048         /* Pick the account */
5049         iter = tny_list_create_iterator (headers);
5050         header = TNY_HEADER (tny_iterator_get_current (iter));
5051         folder = tny_header_get_folder (header);
5052         account = tny_folder_get_account (folder);
5053         g_object_unref (folder);
5054         g_object_unref (header);
5055         g_object_unref (iter);
5056
5057         /* Connect and perform the message retrieval */
5058         modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5059                                              g_object_ref (account), 
5060                                              retrieve_msg_contents_performer, 
5061                                              g_object_ref (headers));
5062
5063         /* Frees */
5064         g_object_unref (account);
5065         g_object_unref (headers);
5066 }
5067
5068 void
5069 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5070 {
5071         g_return_if_fail (MODEST_IS_WINDOW (window));
5072
5073         /* Update dimmed */
5074         modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5075 }
5076
5077 void
5078 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5079 {
5080         g_return_if_fail (MODEST_IS_WINDOW (window));
5081
5082         /* Update dimmed */
5083         modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5084 }
5085
5086 void
5087 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5088                                           ModestWindow *window)
5089 {
5090         g_return_if_fail (MODEST_IS_WINDOW (window));
5091         
5092         /* Update dimmed */
5093         modest_ui_actions_check_menu_dimming_rules (window);
5094 }
5095
5096 void
5097 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5098                                           ModestWindow *window)
5099 {
5100         g_return_if_fail (MODEST_IS_WINDOW (window));
5101
5102         /* Update dimmed */
5103         modest_ui_actions_check_menu_dimming_rules (window);
5104 }
5105
5106 void
5107 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5108                                           ModestWindow *window)
5109 {
5110         g_return_if_fail (MODEST_IS_WINDOW (window));
5111
5112         /* Update dimmed */
5113         modest_ui_actions_check_menu_dimming_rules (window);
5114 }
5115
5116 void
5117 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5118                                             ModestWindow *window)
5119 {
5120         g_return_if_fail (MODEST_IS_WINDOW (window));
5121
5122         /* Update dimmed */
5123         modest_ui_actions_check_menu_dimming_rules (window);
5124 }
5125
5126 void
5127 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5128                                           ModestWindow *window)
5129 {
5130         g_return_if_fail (MODEST_IS_WINDOW (window));
5131
5132         /* Update dimmed */
5133         modest_ui_actions_check_menu_dimming_rules (window);
5134 }
5135
5136 void
5137 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5138                                           ModestWindow *window)
5139 {
5140         g_return_if_fail (MODEST_IS_WINDOW (window));
5141
5142         /* Update dimmed */
5143         modest_ui_actions_check_menu_dimming_rules (window);
5144 }
5145
5146 void
5147 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5148                                                  ModestWindow *window)
5149 {
5150         g_return_if_fail (MODEST_IS_WINDOW (window));
5151
5152         /* Update dimmed */
5153         modest_ui_actions_check_menu_dimming_rules (window);
5154 }
5155
5156 void
5157 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5158                                                      ModestWindow *window)
5159 {
5160         g_return_if_fail (MODEST_IS_WINDOW (window));
5161
5162         /* Update dimmed */
5163         modest_ui_actions_check_menu_dimming_rules (window);
5164 }
5165
5166 void
5167 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5168                                                      ModestWindow *window)
5169 {
5170         g_return_if_fail (MODEST_IS_WINDOW (window));
5171
5172         /* Update dimmed */
5173         modest_ui_actions_check_menu_dimming_rules (window);
5174 }
5175
5176 void
5177 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5178 {
5179         g_return_if_fail (MODEST_IS_WINDOW (window));
5180
5181         modest_platform_show_search_messages (GTK_WINDOW (window));
5182 }
5183
5184 void     
5185 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5186 {
5187         g_return_if_fail (MODEST_IS_WINDOW (win));
5188         modest_platform_show_addressbook (GTK_WINDOW (win));
5189 }
5190
5191
5192 void
5193 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5194                                           ModestWindow *window)
5195 {
5196         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5197
5198         modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5199 }
5200
5201 static void 
5202 on_send_receive_finished (ModestMailOperation  *mail_op, 
5203                            gpointer user_data)
5204 {
5205         GtkWidget *header_view, *folder_view;
5206         TnyFolderStore *folder_store;
5207         ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
5208
5209         /* Set send/receive operation finished */       
5210         modest_main_window_notify_send_receive_completed (main_win);
5211
5212         /* Don't refresh the current folder if there were any errors */
5213         if (modest_mail_operation_get_status (mail_op) !=
5214             MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5215                 return;
5216         
5217         /* Refresh the current folder if we're viewing a window. We do
5218            this because the user won't be able to see the new mails in
5219            the selected folder after a Send&Receive because it only
5220            performs a poke_status, i.e, only the number of read/unread
5221            messages is updated, but the new headers are not
5222            downloaded */
5223         folder_view = modest_main_window_get_child_widget (main_win, 
5224                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5225         if (!folder_view)
5226                 return;
5227
5228         folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5229         
5230         /* Do not need to refresh INBOX again because the
5231            update_account does it always automatically */
5232         if (folder_store && TNY_IS_FOLDER (folder_store) && 
5233             tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
5234                 ModestMailOperation *refresh_op;
5235
5236                 header_view = modest_main_window_get_child_widget (main_win,
5237                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5238                 
5239                 /* We do not need to set the contents style
5240                    because it hasn't changed. We also do not
5241                    need to save the widget status. Just force
5242                    a refresh */
5243                 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
5244                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
5245                 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
5246                                                       folder_refreshed_cb, main_win);
5247                 g_object_unref (refresh_op);
5248         }
5249         
5250         if (folder_store)
5251                 g_object_unref (folder_store);
5252 }
5253
5254
5255 void 
5256 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self, 
5257                                                 TnyHeader *header, 
5258                                                 TnyMsg *msg, 
5259                                                 GError *err, 
5260                                                 gpointer user_data)
5261 {
5262         const gchar* server_name = NULL;
5263         TnyTransportAccount *server_account;
5264         gchar *message = NULL;
5265
5266         /* Don't show anything if the user cancelled something */
5267         if (err->code == TNY_SYSTEM_ERROR_CANCEL)
5268                 return;
5269
5270         /* Get the server name: */
5271         server_account = 
5272                 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
5273         if (server_account) {
5274                 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
5275                         
5276                 g_object_unref (server_account);
5277                 server_account = NULL;
5278         }
5279         
5280         g_return_if_fail (server_name);
5281
5282         /* Show the appropriate message text for the GError: */
5283         switch (err->code) {
5284         case TNY_SERVICE_ERROR_CONNECT:
5285                 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
5286                 break;
5287         case TNY_SERVICE_ERROR_AUTHENTICATE:
5288                 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
5289                 break;
5290         case TNY_SERVICE_ERROR_SEND:
5291                 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
5292                 break;
5293         default:
5294                 g_warning ("%s: unexpected ERROR %d",
5295                            __FUNCTION__, err->code);
5296                 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
5297                 break;  
5298         }
5299         
5300         /* TODO if the username or the password where not defined we
5301            should show the Accounts Settings dialog or the Connection
5302            specific SMTP server window */
5303
5304         modest_platform_run_information_dialog (NULL, message);
5305         g_free (message);
5306 }
5307
5308 void
5309 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5310                                                 gchar *msg_id, 
5311                                                 guint status,
5312                                                 gpointer user_data)
5313 {
5314         ModestMainWindow *main_window = NULL;
5315         ModestWindowMgr *mgr = NULL;
5316         GtkWidget *folder_view = NULL, *header_view = NULL;
5317         TnyFolderStore *selected_folder = NULL;
5318         TnyFolderType folder_type;
5319
5320         mgr = modest_runtime_get_window_mgr ();
5321         main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
5322                                                                              FALSE));/* don't create */
5323         if (!main_window)
5324                 return;
5325
5326         /* Check if selected folder is OUTBOX */
5327         folder_view = modest_main_window_get_child_widget (main_window,
5328                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5329         header_view = modest_main_window_get_child_widget (main_window,
5330                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5331
5332         selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5333         if (!TNY_IS_FOLDER (selected_folder)) 
5334                 goto frees;
5335
5336         /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5337 #if GTK_CHECK_VERSION(2, 8, 0) 
5338         folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder)); 
5339         if (folder_type ==  TNY_FOLDER_TYPE_OUTBOX) {           
5340                 GtkTreeViewColumn *tree_column;
5341
5342                 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view), 
5343                                                         TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5344                 gtk_tree_view_column_queue_resize (tree_column);
5345         }
5346 #else
5347         gtk_widget_queue_draw (header_view);
5348 #endif          
5349
5350         /* Rerun dimming rules, because the message could become deletable for example */
5351         modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window), 
5352                                                  MODEST_DIMMING_RULES_TOOLBAR);
5353         
5354         /* Free */
5355  frees:
5356         if (selected_folder != NULL)
5357                 g_object_unref (selected_folder);
5358 }
5359
5360 void 
5361 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
5362                                                TnyAccount *account)
5363 {
5364         ModestTransportStoreProtocol proto;
5365         const gchar *proto_name;
5366         gchar *error_note = NULL;
5367         
5368         proto_name = tny_account_get_proto (account);
5369         proto = modest_protocol_info_get_transport_store_protocol (proto_name);
5370         
5371         switch (proto) {
5372         case MODEST_PROTOCOL_STORE_POP:
5373                 error_note = g_strdup_printf (_("emev_ni_ui_pop3_msg_connect_error"), 
5374                                               tny_account_get_hostname (account));
5375                 break;
5376         case MODEST_PROTOCOL_STORE_IMAP:
5377                 error_note = g_strdup_printf (_("emev_ni_ui_imap_connect_server_error"), 
5378                                               tny_account_get_hostname (account));
5379                 break;
5380         case MODEST_PROTOCOL_STORE_MAILDIR:
5381         case MODEST_PROTOCOL_STORE_MBOX:
5382                 error_note = g_strdup (_("emev_nc_mailbox_notavailable"));
5383                 break;
5384         default:
5385                 g_warning ("%s: This should not be reached", __FUNCTION__);
5386         }
5387
5388         if (error_note) {
5389                 modest_platform_run_information_dialog (parent_window, error_note);
5390                 g_free (error_note);
5391         }
5392 }