da10328dba4ca10afc6bbbd9d589a549f017b991
[modest] / src / maemo / modest-main-window.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 #include <glib/gi18n.h>
31 #include <gtk/gtktreeviewcolumn.h>
32 #include <tny-account-store-view.h>
33 #include <tny-simple-list.h>
34 #include <tny-list.h>
35 #include <tny-iterator.h>
36 #include <tny-maemo-conic-device.h>
37 #include "modest-hildon-includes.h"
38 #include "modest-defs.h"
39 #include <string.h>
40
41 #include "widgets/modest-main-window.h"
42 #include "widgets/modest-msg-edit-window.h"
43 #include "widgets/modest-account-view-window.h"
44 #include "modest-runtime.h"
45 #include "modest-account-mgr-helpers.h"
46 #include "modest-platform.h"
47 #include "modest-widget-memory.h"
48 #include "modest-window-priv.h"
49 #include "modest-main-window-ui.h"
50 #include "modest-main-window-ui-dimming.h"
51 #include "modest-account-mgr.h"
52 #include "modest-tny-account.h"
53 #include "modest-tny-folder.h"
54 #include "modest-conf.h"
55 #include <modest-maemo-utils.h>
56 #include "modest-tny-platform-factory.h"
57 #include "modest-tny-msg.h"
58 #include "modest-mail-operation.h"
59 #include "modest-icon-names.h"
60 #include "modest-progress-bar-widget.h"
61 #include "modest-text-utils.h"
62 #include "modest-ui-dimming-manager.h"
63 #include "maemo/modest-osso-state-saving.h"
64 #include "modest-text-utils.h"
65
66 #ifdef MODEST_HAVE_HILDON0_WIDGETS
67 #include <hildon-widgets/hildon-program.h>
68 #else
69 #include <hildon/hildon-program.h>
70 #endif /*MODEST_HAVE_HILDON0_WIDGETS*/
71
72 #define MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS "ModestMainWindowActionAdditions"
73
74 #define XALIGN 0.5
75 #define YALIGN 0.0
76 #define XSPACE 1
77 #define YSPACE 0
78
79 /* 'private'/'protected' functions */
80 static void modest_main_window_class_init    (ModestMainWindowClass *klass);
81 static void modest_main_window_init          (ModestMainWindow *obj);
82 static void modest_main_window_finalize      (GObject *obj);
83 static gboolean modest_main_window_window_state_event (GtkWidget *widget, 
84                                                            GdkEventWindowState *event, 
85                                                            gpointer userdata);
86
87 static void connect_signals (ModestMainWindow *self);
88
89 static void restore_settings (ModestMainWindow *self, gboolean do_folder_view_too);
90 static void save_state (ModestWindow *self);
91
92 static void modest_main_window_show_toolbar   (ModestWindow *window,
93                                                gboolean show_toolbar);
94
95 static void cancel_progressbar (GtkToolButton *toolbutton,
96                                 ModestMainWindow *self);
97
98 static void         on_queue_changed                     (ModestMailOperationQueue *queue,
99                                                           ModestMailOperation *mail_op,
100                                                           ModestMailOperationQueueNotification type,
101                                                           ModestMainWindow *self);
102
103 static gboolean on_zoom_minus_plus_not_implemented (ModestWindow *window);
104
105 static void on_account_update                 (TnyAccountStore *account_store, 
106                                                const gchar *account_name,
107                                                gpointer user_data);
108
109 static gboolean on_inner_widgets_key_pressed  (GtkWidget *widget,
110                                                GdkEventKey *event,
111                                                gpointer user_data);
112
113 static void on_configuration_key_changed      (ModestConf* conf, 
114                                                const gchar *key, 
115                                                ModestConfEvent event, 
116                                                ModestMainWindow *self);
117
118 static void set_toolbar_mode                  (ModestMainWindow *self, 
119                                                ModestToolBarModes mode);
120
121 static gboolean set_toolbar_transfer_mode     (ModestMainWindow *self); 
122
123 static void on_show_account_action_activated      (GtkAction *action,
124                                                    gpointer user_data);
125
126 static void on_refresh_account_action_activated   (GtkAction *action,
127                                                    gpointer user_data);
128
129 static void on_send_receive_csm_activated         (GtkMenuItem *item,
130                                                    gpointer user_data);
131
132 static void
133 _on_msg_count_changed (ModestHeaderView *header_view,
134                        TnyFolder *folder,
135                        TnyFolderChange *change,
136                        ModestMainWindow *main_window);
137
138 static void
139 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self);
140
141
142 static GtkWidget * create_empty_view (void);
143
144 static gboolean
145 on_folder_view_focus_in (GtkWidget *widget,
146                          GdkEventFocus *event,
147                          gpointer userdata);
148 static gboolean
149 on_header_view_focus_in (GtkWidget *widget,
150                          GdkEventFocus *event,
151                          gpointer userdata);
152 static void 
153 modest_main_window_on_folder_selection_changed (ModestFolderView *folder_view,
154                                                 TnyFolderStore *folder_store, 
155                                                 gboolean selected,
156                                                 ModestMainWindow *main_window);
157
158 /* list my signals */
159 enum {
160         /* MY_SIGNAL_1, */
161         /* MY_SIGNAL_2, */
162         LAST_SIGNAL
163 };
164
165 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
166 struct _ModestMainWindowPrivate {
167         GtkWidget *msg_paned;
168         GtkWidget *main_paned;
169         GtkWidget *main_vbox;
170         GtkWidget *contents_widget;
171         GtkWidget *empty_view;
172
173         /* Progress observers */
174         GtkWidget        *progress_bar;
175         GSList           *progress_widgets;
176
177         /* Tollbar items */
178         GtkWidget   *progress_toolitem;
179         GtkWidget   *cancel_toolitem;
180         GtkWidget   *sort_toolitem;
181         GtkWidget   *refresh_toolitem;
182         ModestToolBarModes current_toolbar_mode;
183
184         /* Merge ids used to add/remove accounts to the ViewMenu*/
185         GByteArray *merge_ids;
186
187         /* On-demand widgets */
188         GtkWidget *accounts_popup;
189         GtkWidget *details_widget;
190
191         /* Optimized view enabled */
192         gboolean optimized_view;
193
194         /* Optimized view enabled */
195         gboolean send_receive_in_progress;
196
197         ModestHeaderView *header_view;
198         ModestFolderView *folder_view;
199
200         ModestMainWindowStyle style;
201         ModestMainWindowContentsStyle contents_style;
202
203         guint progress_bar_timeout;
204
205         /* Signal handler UIDs */
206         gint queue_changed_handler_uid; 
207         GList *queue_err_signals;
208 };
209 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
210                                                 MODEST_TYPE_MAIN_WINDOW, \
211                                                 ModestMainWindowPrivate))
212
213 typedef struct _GetMsgAsyncHelper {
214         ModestMainWindowPrivate *main_window_private;
215         guint action;
216         ModestTnyMsgReplyType reply_type;
217         ModestTnyMsgForwardType forward_type;
218         gchar *from;
219         TnyIterator *iter;
220 } GetMsgAsyncHelper;
221
222
223 /* globals */
224 static GtkWindowClass *parent_class = NULL;
225
226
227 /* Private actions */
228 /* This is the context sensitive menu: */
229 static const GtkActionEntry modest_folder_view_action_entries [] = {
230
231         /* Folder View CSM actions */
232         { "FolderViewCSMNewFolder", NULL, N_("mcen_ti_new_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
233         { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
234         { "FolderViewCSMPasteMsgs", NULL, N_("mcen_me_inbox_paste"), NULL, NULL,  G_CALLBACK (modest_ui_actions_on_paste)},
235         { "FolderViewCSMDeleteFolder", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
236         { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_search_messages) },
237         { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
238 };
239
240 static const GtkActionEntry modest_header_view_action_entries [] = {
241
242         /* Header View CSM actions */
243         { "HeaderViewCSMOpen",          NULL,  N_("mcen_me_inbox_open"),        NULL,       NULL, G_CALLBACK (modest_ui_actions_on_open) },
244         { "HeaderViewCSMReply",         NULL,  N_("mcen_me_inbox_reply"),       NULL,      NULL, G_CALLBACK (modest_ui_actions_on_reply) },
245         { "HeaderViewCSMReplyAll",      NULL,  N_("mcen_me_inbox_replytoall"),  NULL,      NULL, G_CALLBACK (modest_ui_actions_on_reply_all) },
246         { "HeaderViewCSMForward",       NULL,  N_("mcen_me_inbox_forward"),     NULL,      NULL, G_CALLBACK (modest_ui_actions_on_forward) },
247         { "HeaderViewCSMCut",           NULL,  N_("mcen_me_inbox_cut"),         "<CTRL>X", NULL, G_CALLBACK (modest_ui_actions_on_cut) },
248         { "HeaderViewCSMCopy",          NULL,  N_("mcen_me_inbox_copy"),        "<CTRL>C", NULL, G_CALLBACK (modest_ui_actions_on_copy) },
249         { "HeaderViewCSMPaste",         NULL,  N_("mcen_me_inbox_paste"),       "<CTRL>V", NULL, G_CALLBACK (modest_ui_actions_on_paste) },
250         { "HeaderViewCSMDelete",        NULL,  N_("mcen_me_inbox_delete"),      NULL,      NULL, G_CALLBACK (modest_ui_actions_on_delete) },
251         { "HeaderViewCSMCancelSending", NULL,  N_("mcen_me_outbox_cancelsend"), NULL,      NULL, NULL },
252         { "HeaderViewCSMHelp",          NULL,  N_("mcen_me_inbox_help"),        NULL,      NULL, G_CALLBACK (modest_ui_actions_on_help) },
253 };
254
255 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
256         { "ToolbarToggleView", MODEST_STOCK_SPLIT_VIEW, N_("gqn_toolb_rss_fldonoff"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), FALSE },
257 };
258
259 /************************************************************************/
260
261 GType
262 modest_main_window_get_type (void)
263 {
264         static GType my_type = 0;
265         if (!my_type) {
266                 static const GTypeInfo my_info = {
267                         sizeof(ModestMainWindowClass),
268                         NULL,           /* base init */
269                         NULL,           /* base finalize */
270                         (GClassInitFunc) modest_main_window_class_init,
271                         NULL,           /* class finalize */
272                         NULL,           /* class data */
273                         sizeof(ModestMainWindow),
274                         1,              /* n_preallocs */
275                         (GInstanceInitFunc) modest_main_window_init,
276                         NULL
277                 };
278                 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
279                                                   "ModestMainWindow",
280                                                   &my_info, 0);
281         }
282         return my_type;
283 }
284
285 static void
286 modest_main_window_class_init (ModestMainWindowClass *klass)
287 {
288         GObjectClass *gobject_class;
289         gobject_class = (GObjectClass*) klass;
290         ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
291
292         parent_class            = g_type_class_peek_parent (klass);
293         gobject_class->finalize = modest_main_window_finalize;
294
295         g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
296         
297         modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
298         modest_window_class->save_state_func = save_state;
299         modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
300         modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
301 }
302
303 static void
304 modest_main_window_init (ModestMainWindow *obj)
305 {
306         ModestMainWindowPrivate *priv;
307
308         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
309
310         priv->queue_err_signals = NULL;
311         priv->msg_paned    = NULL;
312         priv->main_paned   = NULL;      
313         priv->main_vbox    = NULL;
314         priv->header_view  = NULL;
315         priv->folder_view  = NULL;
316         priv->contents_widget  = NULL;
317         priv->accounts_popup  = NULL;
318         priv->details_widget  = NULL;
319         priv->empty_view  = NULL;
320         priv->progress_widgets  = NULL;
321         priv->progress_bar = NULL;
322         priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
323         priv->style  = MODEST_MAIN_WINDOW_STYLE_SPLIT;
324         priv->contents_style  = -1; /* invalid contents style. We need this to select it for the first time */
325         priv->merge_ids = NULL;
326         priv->optimized_view  = FALSE;
327         priv->send_receive_in_progress  = FALSE;
328         priv->progress_bar_timeout = 0;
329         priv->queue_changed_handler_uid = 0;
330 }
331
332 static void
333 modest_main_window_finalize (GObject *obj)
334 {
335         ModestMainWindowPrivate *priv;
336
337         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
338
339         modest_main_window_cleanup_queue_error_signals ((ModestMainWindow *) obj);
340
341         g_slist_free (priv->progress_widgets);
342
343         g_byte_array_free (priv->merge_ids, TRUE);
344
345         if (priv->progress_bar_timeout > 0) {
346                 g_source_remove (priv->progress_bar_timeout);
347                 priv->progress_bar_timeout = 0;
348         }
349
350         /* Disconnect signal handlers */
351         if (priv->queue_changed_handler_uid)
352                 g_signal_handler_disconnect (modest_runtime_get_mail_operation_queue (),
353                                              priv->queue_changed_handler_uid);
354
355         G_OBJECT_CLASS(parent_class)->finalize (obj);
356 }
357
358 GtkWidget*
359 modest_main_window_get_child_widget (ModestMainWindow *self,
360                                      ModestWidgetType widget_type)
361 {
362         ModestMainWindowPrivate *priv;
363         GtkWidget *widget;
364         
365         g_return_val_if_fail (self, NULL);
366         g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_WIDGET_TYPE_NUM,
367                               NULL);
368         
369         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
370
371         switch (widget_type) {
372         case MODEST_WIDGET_TYPE_HEADER_VIEW:
373                 widget = (GtkWidget*)priv->header_view; break;
374         case MODEST_WIDGET_TYPE_FOLDER_VIEW:
375                 widget = (GtkWidget*)priv->folder_view; break;
376         default:
377                 return NULL;
378         }
379
380         return widget ? GTK_WIDGET(widget) : NULL;
381 }
382
383
384 static void
385 restore_settings (ModestMainWindow *self, gboolean do_folder_view_too)
386 {
387         ModestConf *conf;
388         ModestMainWindowPrivate *priv;
389
390         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
391
392         conf = modest_runtime_get_conf ();
393
394         modest_widget_memory_restore (conf, G_OBJECT(self),
395                                       MODEST_CONF_MAIN_WINDOW_KEY);
396
397         modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
398                                       MODEST_CONF_HEADER_VIEW_KEY);
399
400         if (do_folder_view_too)
401                 modest_widget_memory_restore (conf, G_OBJECT(priv->folder_view),
402                                       MODEST_CONF_FOLDER_VIEW_KEY);
403
404         modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
405                                       MODEST_CONF_MAIN_PANED_KEY);
406
407         /* We need to force a redraw here in order to get the right
408            position of the horizontal paned separator */
409         gtk_widget_show (GTK_WIDGET (self));
410 }
411
412
413 static void
414 save_state (ModestWindow *window)
415 {
416         ModestConf *conf;
417         ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
418         ModestMainWindowPrivate *priv;
419                 
420         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
421         conf = modest_runtime_get_conf ();
422         
423         modest_widget_memory_save (conf,G_OBJECT(self), 
424                                    MODEST_CONF_MAIN_WINDOW_KEY);
425         modest_widget_memory_save (conf, G_OBJECT(priv->main_paned), 
426                                    MODEST_CONF_MAIN_PANED_KEY);
427         //      modest_widget_memory_save (conf, G_OBJECT(priv->header_view), 
428         //                         MODEST_CONF_HEADER_VIEW_KEY);
429         modest_widget_memory_save (conf, G_OBJECT(priv->folder_view), 
430                                    MODEST_CONF_FOLDER_VIEW_KEY);
431 }
432
433 static void
434 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
435 {
436         if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
437                 gtk_scrolled_window_add_with_viewport
438                         (GTK_SCROLLED_WINDOW(win), widget);
439         else
440                 gtk_container_add (GTK_CONTAINER(win),
441                                    widget);
442 }
443
444
445 /* static gboolean */
446 /* on_delete_event (GtkWidget *widget, GdkEvent  *event, ModestMainWindow *self) */
447 /* { */
448 /*      modest_window_save_state (MODEST_WINDOW(self)); */
449 /*      return FALSE; */
450 /* } */
451
452 typedef struct
453 {
454         ModestMainWindow *self;
455         TnySendQueue *queue;
456         TnyHeader *header;
457 } OnResponseInfo;
458
459 static void
460 on_response (GtkDialog *dialog, gint arg1, gpointer user_data)
461 {
462         OnResponseInfo *info = (OnResponseInfo *) user_data;
463         ModestMainWindow *self = info->self;
464         TnyHeader *header = info->header;
465         TnySendQueue *queue = info->queue;
466
467         if (arg1 == GTK_RESPONSE_YES) {
468                 TnyFolder *outbox = tny_send_queue_get_outbox (queue);
469                 tny_folder_remove_msg (outbox, header, NULL);
470                 tny_folder_sync (outbox, TRUE, NULL);
471                 g_object_unref (outbox);
472         }
473
474         g_object_unref (queue);
475         g_object_unref (header);
476         g_object_unref (self);
477
478         gtk_widget_destroy (GTK_WIDGET (dialog));
479         g_slice_free (OnResponseInfo, info);
480 }
481
482
483 static void
484 on_sendqueue_error_happened (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, GError *err, ModestMainWindow *user_data)
485 {
486         if (header) {
487                 gchar *str = g_strdup_printf ("%s. Do you want to remove the message (%s)?",
488                         err->message, tny_header_get_subject (header));
489                 OnResponseInfo *info = g_slice_new (OnResponseInfo);
490                 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (user_data), 0,
491                         GTK_MESSAGE_ERROR, GTK_BUTTONS_YES_NO, str);
492                 g_free (str);
493                 info->queue = g_object_ref (self);
494                 info->self = g_object_ref (user_data);
495                 info->header = g_object_ref (header);
496                 g_signal_connect (G_OBJECT (dialog), "response",
497                         G_CALLBACK (on_response), info);
498                 gtk_widget_show_all (dialog);
499         }
500 }
501
502 typedef struct {
503         TnySendQueue *queue;
504         guint signal;
505 } QueueErrorSignal;
506
507 static void
508 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
509 {
510         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
511
512         GList *oerrsignals = priv->queue_err_signals;
513         while (oerrsignals) {
514                 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
515                 g_signal_handler_disconnect (esignal->queue, esignal->signal);
516                 g_slice_free (QueueErrorSignal, esignal);
517                 oerrsignals = g_list_next (oerrsignals);
518         }
519         g_list_free (priv->queue_err_signals);
520         priv->queue_err_signals = NULL;
521 }
522
523 static void
524 on_account_store_connecting_finished (TnyAccountStore *store, ModestMainWindow *self)
525 {
526         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
527
528         /* When going online, do the equivalent of pressing the send/receive button, 
529          * as per the specification:
530          * (without the check for >0 accounts, though that is not specified): */
531
532         TnyDevice *device = tny_account_store_get_device (store);
533
534         /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (priv->folder_view), store); */
535         
536         /* Check that we are really online.
537          * This signal should not be emitted when we are not connected, 
538          * but it seems to happen sometimes: */
539          if (!tny_device_is_online (device))
540                 return;
541                 
542         const gchar *iap_id = tny_maemo_conic_device_get_current_iap_id (TNY_MAEMO_CONIC_DEVICE (device));
543         printf ("DEBUG: %s: connection id=%s\n", __FUNCTION__, iap_id);
544         
545         /* Stop the existing send queues: */
546         modest_runtime_remove_all_send_queues ();
547         
548         /* Create the send queues again, using the appropriate transport accounts 
549          * for this new connection.
550          * This could be the first time that they are created if this is the first 
551          * connection. */
552         /* TODO: Does this really destroy the TnySendQueues and their threads
553          * We do not want 2 TnySendQueues to exist with the same underlying 
554          * outbox directory. */
555
556         modest_main_window_cleanup_queue_error_signals (self);
557
558         GSList *account_names = modest_account_mgr_account_names (
559                 modest_runtime_get_account_mgr(), 
560                 TRUE /* enabled accounts only */);
561         GSList *iter = account_names;
562         while (iter) {
563                 const gchar *account_name = (const gchar*)(iter->data);
564                         if (account_name) {
565                         TnyTransportAccount *account = TNY_TRANSPORT_ACCOUNT (
566                                 modest_tny_account_store_get_transport_account_for_open_connection
567                                                  (modest_runtime_get_account_store(), account_name));
568                         if (account) {
569                                 /* Q: Is this the first location where the send-queues are requested? */
570                                 QueueErrorSignal *esignal = g_slice_new (QueueErrorSignal);
571                                 printf ("debug: %s:\n  Transport account for %s: %s\n", __FUNCTION__, account_name, 
572                                         tny_account_get_id(TNY_ACCOUNT(account)));
573                                 esignal->queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (account));
574                                 esignal->signal = g_signal_connect (G_OBJECT (esignal->queue), "error-happened",
575                                         G_CALLBACK (on_sendqueue_error_happened), self);
576                                 priv->queue_err_signals = g_list_prepend (priv->queue_err_signals, esignal);
577                         }
578                 }
579                 
580                 iter = g_slist_next (iter);
581         }
582
583         modest_account_mgr_free_account_names (account_names);
584         account_names = NULL;
585         
586         modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (self));
587 }
588
589 static void
590 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
591 {
592         g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
593
594         /* Update dimmed */     
595         modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");  
596 }
597
598 static void
599 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
600 {
601         g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
602
603         /* Update visibility */
604
605         /* Update dimmed */     
606         modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");  
607 }
608
609 static void
610 connect_signals (ModestMainWindow *self)
611 {       
612         ModestWindowPrivate *parent_priv;
613         ModestMainWindowPrivate *priv;
614         GtkWidget *menu;
615         
616         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
617         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
618
619         /* folder view */
620         g_signal_connect (G_OBJECT(priv->folder_view), "key-press-event",
621                           G_CALLBACK(on_inner_widgets_key_pressed), self);
622         g_signal_connect (G_OBJECT(priv->folder_view), "folder_selection_changed",
623                           G_CALLBACK(modest_main_window_on_folder_selection_changed), self);
624         g_signal_connect (G_OBJECT(priv->folder_view), "folder-display-name-changed",
625                           G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
626         g_signal_connect (G_OBJECT (priv->folder_view), "focus-in-event", 
627                           G_CALLBACK (on_folder_view_focus_in), self);
628
629         /* Folder view CSM */
630         menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
631         gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
632         g_signal_connect (G_OBJECT(priv->folder_view), "tap-and-hold",
633                           G_CALLBACK(_folder_view_csm_menu_activated),
634                           self);
635         /* header view */
636         g_signal_connect (G_OBJECT(priv->header_view), "header_selected",
637                           G_CALLBACK(modest_ui_actions_on_header_selected), self);
638         g_signal_connect (G_OBJECT(priv->header_view), "header_activated",
639                           G_CALLBACK(modest_ui_actions_on_header_activated), self);
640         g_signal_connect (G_OBJECT(priv->header_view), "item_not_found",
641                           G_CALLBACK(modest_ui_actions_on_item_not_found), self);
642         g_signal_connect (G_OBJECT(priv->header_view), "key-press-event",
643                           G_CALLBACK(on_inner_widgets_key_pressed), self);
644         g_signal_connect (G_OBJECT(priv->header_view), "msg_count_changed",
645                           G_CALLBACK(_on_msg_count_changed), self);
646         g_signal_connect (G_OBJECT (priv->header_view), "focus-in-event",
647                           G_CALLBACK (on_header_view_focus_in), self);
648
649         /* Header view CSM */
650         menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
651         gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
652         g_signal_connect (G_OBJECT(priv->header_view), "tap-and-hold",
653                           G_CALLBACK(_header_view_csm_menu_activated),
654                           self);
655         
656         /* window */
657 /*      g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self); */
658         g_signal_connect (G_OBJECT (self), "window-state-event",
659                           G_CALLBACK (modest_main_window_window_state_event),
660                           NULL);
661         
662         /* Mail Operation Queue */
663         priv->queue_changed_handler_uid = 
664                 g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
665                                   "queue-changed", G_CALLBACK (on_queue_changed), self);
666
667         /* Track changes in the device name */
668         g_signal_connect (G_OBJECT(modest_runtime_get_conf ()),
669                           "key_changed", G_CALLBACK (on_configuration_key_changed), 
670                           self);
671
672         /* Track account changes. We need to refresh the toolbar */
673         g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
674                           "account_update", G_CALLBACK (on_account_update),
675                           self);
676
677         /* Account store */
678         g_signal_connect (G_OBJECT (modest_runtime_get_account_store()), 
679                           "password_requested",
680                           G_CALLBACK (modest_ui_actions_on_password_requested), self);
681                           
682         /* Device */
683         g_signal_connect (G_OBJECT(modest_runtime_get_account_store()), 
684                           "connecting-finished",
685                           G_CALLBACK(on_account_store_connecting_finished), self);
686 }
687
688 #if 0
689 /** Idle handler, to send/receive at startup .*/
690 gboolean
691 sync_accounts_cb (ModestMainWindow *win)
692 {
693         modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (win));
694         return FALSE; /* Do not call this idle handler again. */
695 }
696 #endif
697
698 static void on_hildon_program_is_topmost_notify(GObject *self,
699         GParamSpec *propert_param, gpointer user_data)
700 {
701         HildonProgram *app = HILDON_PROGRAM (self);
702         
703         /*
704         ModestWindow* self = MODEST_WINDOW(user_data);
705         */
706         
707         /* Note that use of hildon_program_set_can_hibernate() 
708          * is generally referred to as "setting the killable flag", 
709          * though hibernation does not seem equal to death.
710          * murrayc */
711                  
712         if (hildon_program_get_is_topmost (app)) {
713                 /* Prevent hibernation when the progam comes to the foreground,
714                  * because hibernation should only happen when the application 
715                  * is in the background: */
716                 hildon_program_set_can_hibernate (app, FALSE);
717         } else {
718                 /* Allow hibernation if the program has gone to the background: */
719                 
720                 /* However, prevent hibernation while the settings are being changed: */
721                 const gboolean hibernation_prevented = 
722                         modest_window_mgr_get_hibernation_is_prevented (
723         modest_runtime_get_window_mgr ()); 
724         
725                 if (hibernation_prevented)
726                         hildon_program_set_can_hibernate (app, FALSE);
727                 else {
728                         /* Allow hibernation, after saving the state: */
729                         modest_osso_save_state();
730                         hildon_program_set_can_hibernate (app, TRUE);
731                 }
732         }
733         
734 }
735
736 static void
737 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
738 {
739         GtkWidget *folder_win = (GtkWidget *) user_data;
740         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
741         
742         priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
743         wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
744 /*      wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET(priv->header_view)); */
745
746         gtk_widget_show (GTK_WIDGET (priv->folder_view));
747
748         /* Connect signals */
749         connect_signals ((ModestMainWindow*)self);
750
751         /* Set account store */
752         tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
753                                                   TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
754
755         /* Load previous osso state, for instance if we are being restored from 
756          * hibernation:  */
757         modest_osso_load_state ();
758
759         /* Restore window & widget settings */
760         
761         restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
762
763         /* Check if accounts exist and show the account wizard if not */
764         gboolean accounts_exist = 
765                 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
766
767         if (!accounts_exist) {
768                 /* This is necessary to have the main window shown behind the dialog 
769                 It's an ugly hack... jschmid */
770                 gtk_widget_show_all(GTK_WIDGET(self));
771                 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
772         } else {
773                 GSList *accounts;
774                 GtkAction *send_receive_all;
775                 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
776                 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
777                 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager, 
778                                                               "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
779                 gtk_action_set_visible (send_receive_all, g_slist_length (accounts));
780                 modest_account_mgr_free_account_names (accounts);
781         }
782
783
784 }
785
786 ModestWindow *
787 modest_main_window_new (void)
788 {
789         ModestMainWindow *self = NULL;  
790         ModestMainWindowPrivate *priv = NULL;
791         ModestWindowPrivate *parent_priv = NULL;
792         GtkWidget *folder_win = NULL;
793         ModestDimmingRulesGroup *menu_rules_group = NULL;
794         ModestDimmingRulesGroup *toolbar_rules_group = NULL;
795         GtkActionGroup *action_group = NULL;
796         GError *error = NULL;
797         ModestConf *conf = NULL;
798         GtkAction *action = NULL;
799
800         self  = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
801         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
802         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
803
804         parent_priv->ui_manager = gtk_ui_manager_new();
805         parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
806
807         action_group = gtk_action_group_new ("ModestMainWindowActions");
808         gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
809
810         menu_rules_group = modest_dimming_rules_group_new ("ModestMenuDimmingRules");
811         toolbar_rules_group = modest_dimming_rules_group_new ("ModestToolbarDimmingRules");
812
813         /* Add common actions */
814         gtk_action_group_add_actions (action_group,
815                                       modest_action_entries,
816                                       G_N_ELEMENTS (modest_action_entries),
817                                       self);
818
819         gtk_action_group_add_actions (action_group,
820                                       modest_folder_view_action_entries,
821                                       G_N_ELEMENTS (modest_folder_view_action_entries),
822                                       self);
823
824         gtk_action_group_add_actions (action_group,
825                                       modest_header_view_action_entries,
826                                       G_N_ELEMENTS (modest_header_view_action_entries),
827                                       self);
828
829         gtk_action_group_add_toggle_actions (action_group,
830                                              modest_toggle_action_entries,
831                                              G_N_ELEMENTS (modest_toggle_action_entries),
832                                              self);
833
834         gtk_action_group_add_toggle_actions (action_group,
835                                              modest_main_window_toggle_action_entries,
836                                              G_N_ELEMENTS (modest_main_window_toggle_action_entries),
837                                              self);
838
839         gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
840         g_object_unref (action_group);
841
842         /* Load the UI definition */
843         gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
844                                          MODEST_UIDIR "modest-main-window-ui.xml", &error);
845         if (error != NULL) {
846                 g_warning ("Could not merge modest-ui.xml: %s", error->message);
847                 g_error_free (error);
848                 error = NULL;
849         }
850
851         /* Add common dimming rules */
852         modest_dimming_rules_group_add_rules (menu_rules_group, 
853                                               modest_main_window_menu_dimming_entries,
854                                               G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
855                                               self);
856         modest_dimming_rules_group_add_rules (toolbar_rules_group, 
857                                               modest_main_window_toolbar_dimming_entries,
858                                               G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
859                                               self);
860
861         /* Insert dimming rules group for this window */
862         modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
863         modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
864         g_object_unref (menu_rules_group);
865         g_object_unref (toolbar_rules_group);
866         
867         /* Add accelerators */
868         gtk_window_add_accel_group (GTK_WINDOW (self), 
869                                     gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
870
871         /* Menubar. Update the state of some toggles */
872         parent_priv->menubar = modest_maemo_utils_menubar_to_menu (parent_priv->ui_manager);
873         conf = modest_runtime_get_conf ();
874         action = gtk_ui_manager_get_action (parent_priv->ui_manager, 
875                                             "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
876         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
877                                       modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR, NULL));
878         action = gtk_ui_manager_get_action (parent_priv->ui_manager, 
879                                             "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
880         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
881                                       modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN, NULL));
882         hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
883
884         /* Get device name */
885         modest_maemo_utils_get_device_name ();
886
887         /* header view */
888         priv->header_view =
889                 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
890         if (!priv->header_view)
891                 g_printerr ("modest: cannot instantiate header view\n");
892         modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
893         modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
894                                       MODEST_CONF_HEADER_VIEW_KEY);
895
896         /* Empty view */ 
897         priv->empty_view = create_empty_view ();
898                  
899         /* Create scrolled windows */
900         folder_win = gtk_scrolled_window_new (NULL, NULL);
901         priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
902         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
903                                         GTK_POLICY_NEVER,
904                                         GTK_POLICY_AUTOMATIC);
905         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
906                                         GTK_POLICY_NEVER,
907                                         GTK_POLICY_AUTOMATIC);
908
909         /* paned */
910         priv->main_paned = gtk_hpaned_new ();
911         gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
912         gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
913         gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
914
915         /* putting it all together... */
916         priv->main_vbox = gtk_vbox_new (FALSE, 6);
917         gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
918
919         gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
920         
921         HildonProgram *app = hildon_program_get_instance ();
922         hildon_program_add_window (app, HILDON_WINDOW (self));
923         
924         g_signal_connect (G_OBJECT(app), "notify::is-topmost",
925                 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
926
927         g_signal_connect (G_OBJECT(self), "show",
928                           G_CALLBACK (modest_main_window_on_show), folder_win);
929                 
930
931         restore_settings (MODEST_MAIN_WINDOW(self), FALSE);
932
933         return MODEST_WINDOW(self);
934 }
935
936 gboolean 
937 modest_main_window_close_all (ModestMainWindow *self)
938 {
939         GtkWidget *note;
940         GtkResponseType response;
941
942         /* Create the confirmation dialog MSG-NOT308 */
943         note = hildon_note_new_confirmation_add_buttons (GTK_WINDOW (self),
944                                                          _("emev_nc_close_windows"),
945                                                          _("mcen_bd_yes"), GTK_RESPONSE_YES,
946                                                          _("mcen_bd_no"), GTK_RESPONSE_NO,
947                                                          NULL);
948
949         response = gtk_dialog_run (GTK_DIALOG (note));
950         gtk_widget_destroy (GTK_WIDGET (note));
951
952         if (response == GTK_RESPONSE_YES)
953                 return TRUE;
954         else
955                 return FALSE;
956 }
957
958
959 void 
960 modest_main_window_set_style (ModestMainWindow *self, 
961                               ModestMainWindowStyle style)
962 {
963         ModestMainWindowPrivate *priv;
964         ModestWindowPrivate *parent_priv;
965         GtkAction *action;
966
967         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
968
969         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
970         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
971
972         /* no change -> nothing to do */
973         if (priv->style == style)
974                 return;
975
976         /* Get toggle button */
977         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarToggleView");
978
979         priv->style = style;
980         switch (style) {
981         case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
982                 /* Remove main paned */
983                 g_object_ref (priv->main_paned);
984                 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
985
986                 /* Reparent the contents widget to the main vbox */
987                 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
988
989                 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
990                 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
991                 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
992
993                 if (modest_header_view_has_selected_headers (MODEST_HEADER_VIEW (priv->header_view))) {
994                         TnyList *selection = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (priv->header_view));
995                         TnyIterator *iterator = tny_list_create_iterator (selection);
996                         TnyHeader *header;
997                         tny_iterator_first (iterator);
998                         header = TNY_HEADER (tny_iterator_get_current (iterator));
999                         if (tny_header_get_subject (header))
1000                                 gtk_window_set_title (GTK_WINDOW(self), tny_header_get_subject (header));
1001                         else
1002                                 gtk_window_set_title (GTK_WINDOW (self), _("mail_va_no_subject"));
1003                         g_object_unref (header);
1004                         g_object_unref (iterator);
1005                         g_object_unref (selection);
1006                 }
1007
1008                 break;
1009         case MODEST_MAIN_WINDOW_STYLE_SPLIT:
1010                 /* Remove header view */
1011                 g_object_ref (priv->contents_widget);
1012                 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
1013
1014                 /* Reparent the main paned */
1015                 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
1016                 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1017
1018                 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1019                 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
1020                 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1021
1022                 break;
1023         default:
1024                 g_return_if_reached ();
1025         }
1026
1027         /* Let header view grab the focus if it's being shown */
1028         if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1029                 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1030         else 
1031                 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1032
1033         /* Show changes */
1034         gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1035 }
1036
1037 ModestMainWindowStyle
1038 modest_main_window_get_style (ModestMainWindow *self)
1039 {
1040         ModestMainWindowPrivate *priv;
1041
1042         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1043
1044         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1045         return priv->style;
1046 }
1047
1048
1049
1050 static gboolean
1051 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1052 {
1053         if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1054                 ModestWindowPrivate *parent_priv;
1055                 ModestWindowMgr *mgr;
1056                 gboolean is_fullscreen;
1057                 GtkAction *fs_toggle_action;
1058                 gboolean active;
1059                 
1060                 mgr = modest_runtime_get_window_mgr ();
1061                 
1062                 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1063
1064                 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1065                 
1066                 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1067                 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1068                 if (is_fullscreen != active) {
1069                         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1070                 }
1071         }
1072
1073         return FALSE;
1074
1075 }
1076
1077 static void
1078 set_homogeneous (GtkWidget *widget,
1079                  gpointer data)
1080 {
1081         gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
1082         gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
1083 }
1084
1085 static void 
1086 modest_main_window_show_toolbar (ModestWindow *self,
1087                                  gboolean show_toolbar)
1088 {
1089         ModestMainWindowPrivate *priv = NULL;
1090         ModestWindowPrivate *parent_priv = NULL;        
1091         GtkWidget *reply_button = NULL, *menu = NULL;
1092         GtkWidget *placeholder = NULL;
1093         gint insert_index;
1094
1095         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1096         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1097         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1098
1099         /* Set optimized view status */
1100         priv->optimized_view = !show_toolbar;
1101
1102         if (!parent_priv->toolbar) {
1103                 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
1104                                                                   "/ToolBar");
1105
1106                 /* Set homogeneous toolbar */
1107                 gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar), 
1108                                        set_homogeneous, NULL);
1109         
1110                 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1111                 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1112                 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1113                 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1114                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1115                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1116                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1117                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1118
1119                 /* Add ProgressBar (Transfer toolbar) */ 
1120                 priv->progress_bar = modest_progress_bar_widget_new ();
1121                 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1122                 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1123                 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1124                 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1125                 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1126                 
1127                 /* Connect cancel 'clicked' signal to abort progress mode */
1128                 g_signal_connect(priv->cancel_toolitem, "clicked",
1129                                  G_CALLBACK(cancel_progressbar),
1130                                  self);
1131                 
1132                 /* Add it to the observers list */
1133                 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1134
1135                 /* Add to window */
1136                 hildon_window_add_toolbar (HILDON_WINDOW (self), 
1137                                            GTK_TOOLBAR (parent_priv->toolbar));
1138
1139                 /* Set reply button tap and hold menu */
1140                 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
1141                                                           "/ToolBar/ToolbarMessageReply");
1142                 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1143                                                   "/ToolbarReplyCSM");
1144                 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1145
1146                 /* Set send & receive button tap and hold menu */
1147                 on_account_update (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
1148                                    NULL, self);
1149         }
1150
1151         if (show_toolbar) {
1152                 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */ 
1153                 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1154                 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1155
1156                 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1157                 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1158         } else
1159                 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1160
1161 }
1162
1163 static gint
1164 compare_display_names (ModestAccountData *a,
1165                        ModestAccountData *b)
1166 {
1167         return strcmp (a->display_name, b->display_name);
1168 }
1169
1170 static void 
1171 on_account_update (TnyAccountStore *account_store, 
1172                    const gchar *account_name,
1173                    gpointer user_data)
1174 {
1175         GSList *account_names, *iter, *accounts;
1176         ModestMainWindow *self;
1177         ModestMainWindowPrivate *priv;
1178         ModestWindowPrivate *parent_priv;
1179         ModestAccountMgr *mgr;
1180         gint i, num_accounts;                                   
1181         GtkActionGroup *action_group;
1182         GList *groups;
1183         gchar *default_account;
1184         GtkWidget *send_receive_button, *item;
1185         GtkAction *send_receive_all = NULL;
1186                 
1187         self = MODEST_MAIN_WINDOW (user_data);
1188         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
1189         parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1190
1191         /* Get enabled account IDs */
1192         mgr = modest_runtime_get_account_mgr ();
1193         account_names = modest_account_mgr_account_names (mgr, TRUE);
1194         iter = account_names;
1195         accounts = NULL;
1196
1197         while (iter) {
1198                 ModestAccountData *account_data = 
1199                         modest_account_mgr_get_account_data (mgr, (gchar*) iter->data);
1200                 accounts = g_slist_prepend (accounts, account_data);
1201
1202                 iter = iter->next;
1203         }
1204         modest_account_mgr_free_account_names (account_names);
1205         account_names = NULL;
1206
1207         /* Order the list of accounts by its display name */
1208         accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
1209         num_accounts = g_slist_length (accounts);
1210
1211         send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager, 
1212                                                       "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1213         gtk_action_set_visible (send_receive_all, num_accounts > 1);
1214
1215         /* Delete old send&receive popup items. We can not just do a
1216            menu_detach because it does not work well with
1217            tap_and_hold */
1218         if (priv->accounts_popup)
1219                 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup), 
1220                                        (GtkCallback) gtk_widget_destroy, NULL);
1221
1222         /* Delete old entries in the View menu. Do not free groups, it
1223            belongs to Gtk+ */
1224         groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
1225         while (groups) {
1226                 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
1227                              gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
1228                         gtk_ui_manager_remove_action_group (parent_priv->ui_manager, 
1229                                                             GTK_ACTION_GROUP (groups->data));
1230                         groups = NULL;
1231                         /* Remove uis */
1232                         if (priv->merge_ids) {
1233                                 for (i = 0; i < priv->merge_ids->len; i++)
1234                                         gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
1235                                 g_byte_array_free (priv->merge_ids, TRUE);
1236                         }
1237                         /* We need to call this in order to ensure
1238                            that the new actions are added in the right
1239                            order (alphabetical */
1240                         gtk_ui_manager_ensure_update (parent_priv->ui_manager);
1241                 } else 
1242                         groups = g_list_next (groups);
1243         }
1244         priv->merge_ids = g_byte_array_sized_new (num_accounts);
1245
1246         /* Get send receive button */
1247         send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1248                                                           "/ToolBar/ToolbarSendReceive");
1249
1250         /* Create the menu */
1251         if (num_accounts > 1) {
1252                 if (!priv->accounts_popup)
1253                         priv->accounts_popup = gtk_menu_new ();
1254                 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
1255                 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1256                 g_signal_connect (G_OBJECT (item), 
1257                                   "activate", 
1258                                   G_CALLBACK (on_send_receive_csm_activated),
1259                                   NULL);
1260                 item = gtk_separator_menu_item_new ();
1261                 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1262         }
1263
1264         /* Create a new action group */
1265         default_account = modest_account_mgr_get_default_account (mgr);
1266         action_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
1267         for (i = 0; i < num_accounts; i++) {
1268                 gchar *display_name = NULL;
1269                 
1270                 ModestAccountData *account_data = (ModestAccountData *) g_slist_nth_data (accounts, i);
1271
1272                 /* Create display name. The default account is shown differently */
1273                 if (default_account && account_data->account_name && 
1274                         !(strcmp (default_account, account_data->account_name) == 0)) {
1275                         display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"), 
1276                                                         account_data->display_name);
1277                 }
1278                 else {
1279                         display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"), 
1280                                                         account_data->display_name);
1281                 }
1282
1283                 /* Create action and add it to the action group. The
1284                    action name must be the account name, this way we
1285                    could know in the handlers the account to show */
1286                 if(account_data->account_name) {
1287                         gchar* item_name, *refresh_action_name;
1288                         guint8 merge_id;
1289                         GtkAction *view_account_action, *refresh_account_action;
1290
1291                         view_account_action = gtk_action_new (account_data->account_name,
1292                                                               display_name, NULL, NULL);
1293                         gtk_action_group_add_action (action_group, view_account_action);
1294
1295                         /* Add ui from account data. We allow 2^9-1 account
1296                            changes in a single execution because we're
1297                            downcasting the guint to a guint8 in order to use a
1298                            GByteArray, it should be enough */
1299                         item_name = g_strconcat (account_data->account_name, "Menu", NULL);
1300                         merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
1301                         priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
1302                         gtk_ui_manager_add_ui (parent_priv->ui_manager,
1303                                                merge_id,
1304                                                "/MenuBar/ViewMenu/ViewMenuAdditions",
1305                                                item_name,
1306                                                account_data->account_name,
1307                                                GTK_UI_MANAGER_MENUITEM,
1308                                                FALSE);
1309         
1310                         /* Connect the action signal "activate" */
1311                         g_signal_connect (G_OBJECT (view_account_action),
1312                                           "activate",
1313                                           G_CALLBACK (on_show_account_action_activated),
1314                                           self);
1315
1316                         /* Create the items for the Tools->Send&Receive submenu */
1317                         refresh_action_name = g_strconcat ("SendReceive", account_data->account_name, NULL);
1318                         refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name, 
1319                                                                  display_name, NULL, NULL);
1320                         gtk_action_group_add_action (action_group, refresh_account_action);
1321
1322                         merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
1323                         priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
1324                         gtk_ui_manager_add_ui (parent_priv->ui_manager, 
1325                                                merge_id,
1326                                                "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
1327                                                item_name,
1328                                                refresh_action_name,
1329                                                GTK_UI_MANAGER_MENUITEM,
1330                                                FALSE);
1331                         g_free (refresh_action_name);
1332
1333                         g_signal_connect_data (G_OBJECT (refresh_account_action), 
1334                                                "activate", 
1335                                                G_CALLBACK (on_refresh_account_action_activated), 
1336                                                g_strdup (account_data->account_name),
1337                                                (GClosureNotify) g_free,
1338                                                0);
1339
1340                         /* Create item and add it to the send&receive
1341                            CSM. If there is only one account then
1342                            it'll be no menu */
1343                         if (priv->accounts_popup) {
1344                                 item = gtk_menu_item_new_with_label (display_name);
1345                                 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1346                                 g_signal_connect_data (G_OBJECT (item), 
1347                                                        "activate", 
1348                                                        G_CALLBACK (on_send_receive_csm_activated),
1349                                                        g_strdup (account_data->account_name),
1350                                                        (GClosureNotify) g_free,
1351                                                        0);
1352                         }
1353                         g_free (item_name);
1354                 }
1355
1356                 /* Frees */
1357                 g_free (display_name);
1358                 modest_account_mgr_free_account_data (mgr, account_data);
1359         }
1360         gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 1);
1361
1362         if (priv->accounts_popup) {
1363                 /* Mandatory in order to view the menu contents */
1364                 gtk_widget_show_all (priv->accounts_popup);
1365
1366                 /* Setup tap_and_hold just if was not done before*/
1367                 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
1368                         gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
1369         }
1370
1371         /* Frees */
1372         g_slist_free (accounts);
1373         g_free (default_account);
1374 }
1375
1376 /* 
1377  * This function manages the key events used to navigate between
1378  * header and folder views (when the window is in split view)
1379  *
1380  * FROM         KEY        ACTION
1381  * -------------------------------------------------
1382  * HeaderView   GDK_Left   Move focus to folder view
1383  * FolderView   GDK_Right  Move focus to header view
1384  *
1385  * There is no need to scroll to selected row, the widgets will be the
1386  * responsibles of doing that (probably managing the focus-in event
1387  */
1388 static gboolean 
1389 on_inner_widgets_key_pressed (GtkWidget *widget,
1390                               GdkEventKey *event,
1391                               gpointer user_data)
1392 {
1393         ModestMainWindowPrivate *priv;
1394
1395         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1396
1397         /* Do nothing if we're in SIMPLE style */
1398         if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1399                 return FALSE;
1400
1401         if (MODEST_IS_HEADER_VIEW (widget) && event->keyval == GDK_Left)
1402                 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1403         else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1404                 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1405
1406         return FALSE;
1407 }
1408
1409 static void
1410 set_alignment (GtkWidget *widget,
1411                gpointer data)
1412 {
1413         gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1414         gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1415 }
1416
1417 static GtkWidget *
1418 create_empty_view (void)
1419 {
1420         GtkLabel *label = NULL;
1421         GtkWidget *align = NULL;
1422
1423         align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1424         label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1425         gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);      
1426         gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1427
1428         return GTK_WIDGET(align);
1429 }
1430
1431 static GtkWidget *
1432 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1433 {
1434         /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1435         
1436         GtkWidget *vbox;
1437         GtkWidget *label_w;
1438         gchar *label;
1439         gchar *gray_color_markup;
1440
1441         vbox = gtk_vbox_new (FALSE, 0);
1442
1443         /* Obtain the secondary text color. We need a realized widget, that's why 
1444            we get styled_widget from outside */
1445 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1446         GdkColor color;
1447         gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color);
1448         gray_color_markup = modest_text_utils_get_color_string (&color);
1449 #else
1450         // gray_color_markup is freed below
1451         gray_color_markup = g_strdup ("#BBBBBB");
1452 #endif  
1453         /* Account description: */
1454         
1455         if (modest_tny_account_is_virtual_local_folders (account)
1456                 || (modest_tny_account_is_memory_card_account (account))) {
1457                 gchar *tmp;
1458                 /* Local folders: */
1459         
1460                 /* Get device name */
1461                 gchar *device_name = NULL;
1462                 if (modest_tny_account_is_virtual_local_folders (account))
1463                         device_name = modest_conf_get_string (modest_runtime_get_conf(),
1464                                                       MODEST_CONF_DEVICE_NAME, NULL);
1465                 else
1466                         device_name = g_strdup (tny_account_get_name (account));
1467                                                       
1468                 tmp = g_strdup_printf (_("mcen_fi_localroot_description"), ""); //TODO: Why the ""?
1469                 label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s",
1470                                                  gray_color_markup, tmp, device_name);
1471                 g_free (tmp);
1472                 label_w = gtk_label_new (NULL);
1473                 gtk_label_set_markup (GTK_LABEL (label_w), label);
1474                 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1475                 g_free (device_name);
1476                 g_free (label);
1477         } else {
1478                 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1479                         gtk_box_pack_start (GTK_BOX (vbox), 
1480                                 gtk_label_new (tny_account_get_name (account)), 
1481                                 FALSE, FALSE, 0);
1482                 } else {
1483                         /* Other accounts, such as IMAP and POP: */
1484                         
1485                         GString *proto;
1486                         gchar *tmp;
1487         
1488                         /* Put proto in uppercase */
1489                         proto = g_string_new (tny_account_get_proto (account));
1490                         proto = g_string_ascii_up (proto);
1491                         
1492                         /* note: mcen_fi_localroot_description is something like "%s account"
1493                          * however, we should display "%s account: %s"... therefore, ugly tmp */
1494                         tmp   = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1495                         label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s", 
1496                                                          gray_color_markup, tmp, tny_account_get_name (account));
1497                         g_free (tmp);
1498
1499                         label_w = gtk_label_new (NULL);
1500                         gtk_label_set_markup (GTK_LABEL (label_w), label);
1501                         gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1502                         g_string_free (proto, TRUE);
1503                         g_free (label);
1504                 }
1505         }
1506
1507         /* Message count */
1508         TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1509         label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d", 
1510                                          gray_color_markup, _("mcen_fi_rootfolder_messages"), 
1511                                          modest_tny_folder_store_get_message_count (folder_store));
1512         label_w = gtk_label_new (NULL);
1513         gtk_label_set_markup (GTK_LABEL (label_w), label);
1514         gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1515         g_free (label);
1516
1517         /* Folder count */
1518         label = g_markup_printf_escaped ("<span color='%s'>%s</span>: %d", 
1519                                          gray_color_markup, 
1520                                          _("mcen_fi_rootfolder_folders"), 
1521                                          modest_tny_folder_store_get_folder_count (folder_store));
1522         label_w = gtk_label_new (NULL);
1523         gtk_label_set_markup (GTK_LABEL (label_w), label);
1524         gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1525         g_free (label);
1526
1527         /* Size / Date */
1528         if (modest_tny_account_is_virtual_local_folders (account)
1529                 || modest_tny_account_is_memory_card_account (account)) {
1530
1531                 gchar *size = modest_text_utils_get_display_size (
1532                         modest_tny_folder_store_get_local_size (folder_store));
1533                 
1534                 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s", 
1535                                                  gray_color_markup, _("mcen_fi_rootfolder_size"),
1536                                                  size);
1537                 g_free (size);
1538                 
1539                 label_w = gtk_label_new (NULL);
1540                 gtk_label_set_markup (GTK_LABEL (label_w), label);
1541                 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1542                 g_free (label);
1543         } else if (TNY_IS_ACCOUNT(folder_store)) {
1544                 TnyAccount *account = TNY_ACCOUNT(folder_store);
1545                 
1546                 time_t last_updated;
1547                 gchar *last_updated_string;
1548                 /* Get last updated from configuration */
1549                 last_updated = modest_account_mgr_get_int (modest_runtime_get_account_mgr (), 
1550                                                           tny_account_get_id (account), 
1551                                                           MODEST_ACCOUNT_LAST_UPDATED, 
1552                                                           TRUE);
1553                 if (last_updated > 0) 
1554                         last_updated_string = modest_text_utils_get_display_date(last_updated);
1555                 else
1556                         last_updated_string = g_strdup (_("mcen_va_never"));
1557
1558                 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s", 
1559                                                  gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1560                 label_w = gtk_label_new (NULL);
1561                 gtk_label_set_markup (GTK_LABEL (label_w), label);
1562                 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1563                 g_free (last_updated_string);
1564                 g_free (label);
1565         }
1566
1567         g_free (gray_color_markup);
1568
1569         /* Set alignment */
1570         gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1571
1572         return vbox;
1573 }
1574
1575 gboolean
1576 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1577 {
1578         ModestMainWindowPrivate *priv = NULL;
1579         
1580         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1581
1582         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1583
1584         return priv->send_receive_in_progress;
1585 }
1586
1587 void 
1588 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1589 {
1590         GtkAction *action = NULL;
1591         GtkWidget *widget = NULL;
1592         ModestMainWindowPrivate *priv = NULL;
1593                 
1594         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1595         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1596         
1597         priv->send_receive_in_progress  = TRUE;
1598
1599         action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu"); 
1600         gtk_action_set_sensitive (action, FALSE);
1601 /*         action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1602 /*      gtk_action_set_sensitive (action, FALSE); */
1603         widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");       
1604         gtk_widget_set_sensitive (widget, FALSE);
1605
1606
1607 void 
1608 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1609 {
1610         GtkAction *action = NULL;
1611         GtkWidget *widget = NULL;
1612         ModestMainWindowPrivate *priv = NULL;
1613                 
1614         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1615         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1616
1617         priv->send_receive_in_progress  = FALSE;
1618
1619         action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu"); 
1620         gtk_action_set_sensitive (action, TRUE);
1621 /*         action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu");     */
1622 /*      gtk_action_set_sensitive (action, TRUE); */
1623         widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");       
1624         gtk_widget_set_sensitive (widget, TRUE);
1625
1626
1627
1628 static void
1629 _on_msg_count_changed (ModestHeaderView *header_view,
1630                        TnyFolder *folder,
1631                        TnyFolderChange *change,
1632                        ModestMainWindow *main_window)
1633 {
1634         printf ("DEBUG: %s\n", __FUNCTION__);
1635         gboolean folder_empty = FALSE;
1636         TnyFolderChangeChanged changed;
1637         
1638         g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1639         g_return_if_fail (TNY_IS_FOLDER(folder));
1640         g_return_if_fail (TNY_IS_FOLDER_CHANGE(change));
1641         
1642         changed = tny_folder_change_get_changed (change);
1643         
1644         /* If something changes */
1645         if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1646                 folder_empty = (tny_folder_change_get_new_all_count (change) == 0);     
1647         else
1648                 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1649         
1650         printf ("DEBUG: %s: folder_empty=%d\n", __FUNCTION__, folder_empty);
1651
1652         /* Set contents style of headers view */
1653         if (folder_empty)  {
1654                 modest_main_window_set_contents_style (main_window,
1655                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1656         }
1657         else {
1658                 modest_main_window_set_contents_style (main_window,
1659                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1660         }       
1661 }
1662
1663 void 
1664 modest_main_window_set_contents_style (ModestMainWindow *self, 
1665                                        ModestMainWindowContentsStyle style)
1666 {
1667         ModestMainWindowPrivate *priv;
1668
1669         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1670
1671         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1672
1673         /* We allow to set the same content style than the previously
1674            set if there are details, because it could happen when we're
1675            selecting different accounts consecutively */
1676         if ((priv->contents_style == style) &&
1677             (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1678                 return;
1679
1680         /* Remove previous child. Delete it if it was an account
1681            details widget */
1682         GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1683         if (content) {
1684                 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1685                         g_object_ref (content);
1686                 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1687                         g_object_ref (priv->empty_view);
1688                         gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
1689                 }
1690                 
1691                 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1692         }
1693
1694         priv->contents_style = style;
1695
1696         switch (priv->contents_style) {
1697         case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1698                 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1699                 break;
1700         case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1701         {
1702                 TnyFolderStore *selected_folderstore = 
1703                         modest_folder_view_get_selected (priv->folder_view);
1704                 if (TNY_IS_ACCOUNT (selected_folderstore)) {    
1705                   priv->details_widget = create_details_widget (GTK_WIDGET (self),
1706                                                                 TNY_ACCOUNT (selected_folderstore));
1707
1708                         wrap_in_scrolled_window (priv->contents_widget, 
1709                                          priv->details_widget);
1710                 }
1711                 g_object_unref (selected_folderstore);
1712                 break;
1713         }
1714         case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
1715                 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
1716                 break;
1717         default:
1718                 g_return_if_reached ();
1719         }
1720
1721         /* Show */
1722         gtk_widget_show_all (priv->contents_widget);
1723 }
1724
1725 ModestMainWindowContentsStyle
1726 modest_main_window_get_contents_style (ModestMainWindow *self)
1727 {
1728         ModestMainWindowPrivate *priv;
1729
1730         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1731
1732         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1733         return priv->contents_style;
1734 }
1735
1736
1737 static void 
1738 on_configuration_key_changed (ModestConf* conf, 
1739                               const gchar *key, 
1740                               ModestConfEvent event, 
1741                               ModestMainWindow *self)
1742 {
1743         ModestMainWindowPrivate *priv;
1744         TnyAccount *account;
1745
1746         if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
1747                 return;
1748
1749         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1750
1751         if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1752                 return;
1753
1754         account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
1755         if (TNY_IS_ACCOUNT (account) &&
1756             !strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1757                 GList *children;
1758                 GtkLabel *label;
1759                 const gchar *device_name;
1760                 gchar *new_text;
1761                 
1762                 /* Get label */
1763                 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
1764                 label = GTK_LABEL (children->data);
1765                 
1766                 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1767                                                       MODEST_CONF_DEVICE_NAME, NULL);
1768                 
1769                 new_text = g_strdup_printf ("%s: %s",
1770                                             _("mcen_fi_localroot_description"),
1771                                             device_name);
1772                 
1773                 gtk_label_set_text (label, new_text);
1774                 gtk_widget_show (GTK_WIDGET (label));
1775                 
1776                 g_free (new_text);
1777                 g_list_free (children);
1778         }
1779         g_object_unref (account);
1780 }
1781
1782 static gboolean
1783 set_toolbar_transfer_mode (ModestMainWindow *self)
1784 {
1785         ModestMainWindowPrivate *priv = NULL;
1786         
1787         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1788
1789         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1790
1791         set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
1792         
1793         if (priv->progress_bar_timeout > 0) {
1794                 g_source_remove (priv->progress_bar_timeout);
1795                 priv->progress_bar_timeout = 0;
1796         }
1797
1798         return FALSE;
1799 }
1800
1801 static void 
1802 set_toolbar_mode (ModestMainWindow *self, 
1803                   ModestToolBarModes mode)
1804 {
1805         ModestWindowPrivate *parent_priv = NULL;
1806         ModestMainWindowPrivate *priv = NULL;
1807         GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
1808         
1809         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1810
1811         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1812         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1813
1814         /* In case this was called before the toolbar exists: */
1815         if (!(parent_priv->toolbar))
1816                 return;
1817
1818         g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar)); 
1819         
1820         sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1821         refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1822         cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1823
1824         /* Sets current toolbar mode */
1825         priv->current_toolbar_mode = mode;
1826
1827         /* Show and hide toolbar items */
1828         switch (mode) {
1829         case TOOLBAR_MODE_NORMAL:
1830                 if (sort_action)
1831                         gtk_action_set_visible (sort_action, TRUE);
1832                 if (refresh_action)
1833                         gtk_action_set_visible (refresh_action, TRUE);
1834                 if (priv->progress_toolitem) {
1835                         gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1836                         gtk_widget_hide (priv->progress_toolitem);
1837                 }
1838                 if (priv->progress_bar)
1839                         gtk_widget_hide (priv->progress_bar);
1840                 
1841                 if (cancel_action)
1842                         gtk_action_set_visible (cancel_action, FALSE);
1843 /*              if (priv->sort_toolitem) */
1844 /*                      gtk_widget_show (priv->sort_toolitem); */
1845                 
1846 /*              if (priv->refresh_toolitem) */
1847 /*                      gtk_widget_show (priv->refresh_toolitem); */
1848                         
1849 /*              if (priv->progress_toolitem) */
1850 /*                      gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE); */
1851 /*              if (priv->progress_bar) */
1852 /*                      gtk_widget_hide (priv->progress_bar); */
1853                         
1854 /*              if (priv->cancel_toolitem) */
1855 /*                      gtk_widget_hide (priv->cancel_toolitem); */
1856
1857                 /* Hide toolbar if optimized view is enabled */
1858                 if (priv->optimized_view)
1859                         gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
1860                 break;
1861         case TOOLBAR_MODE_TRANSFER:
1862                 if (sort_action)
1863                         gtk_action_set_visible (sort_action, FALSE);
1864                 if (refresh_action)
1865                         gtk_action_set_visible (refresh_action, FALSE);
1866                 if (cancel_action)
1867                         gtk_action_set_visible (cancel_action, TRUE);
1868                 if (priv->progress_toolitem) {
1869                         gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1870                         gtk_widget_show (priv->progress_toolitem);
1871                 }
1872                 if (priv->progress_bar)
1873                         gtk_widget_show (priv->progress_bar);
1874
1875 /*              if (priv->sort_toolitem) */
1876 /*                      gtk_widget_hide (priv->sort_toolitem); */
1877                 
1878 /*              if (priv->refresh_toolitem) */
1879 /*                      gtk_widget_hide (priv->refresh_toolitem); */
1880                 
1881 /*              if (priv->progress_toolitem) */
1882 /*                      gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE); */
1883 /*              if (priv->progress_bar) */
1884 /*                      gtk_widget_show (priv->progress_bar); */
1885                         
1886 /*              if (priv->cancel_toolitem) */
1887 /*                      gtk_widget_show (priv->cancel_toolitem); */
1888
1889                 /* Show toolbar if it's hiden (optimized view ) */
1890                 if (priv->optimized_view)
1891                         gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1892                 break;
1893         default:
1894                 g_return_if_reached ();
1895         }
1896 }
1897
1898 static void
1899 cancel_progressbar (GtkToolButton *toolbutton,
1900                     ModestMainWindow *self)
1901 {
1902         GSList *tmp;
1903         ModestMainWindowPrivate *priv;
1904         
1905         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1906
1907         /* Get operation observers and cancel its current operation */
1908         tmp = priv->progress_widgets;
1909         while (tmp) {
1910                 modest_progress_object_cancel_current_operation (MODEST_PROGRESS_OBJECT(tmp->data));
1911                 tmp=g_slist_next(tmp);
1912         }
1913 }
1914
1915 static gboolean
1916 observers_empty (ModestMainWindow *self)
1917 {
1918         GSList *tmp = NULL;
1919         ModestMainWindowPrivate *priv;
1920         gboolean is_empty = TRUE;
1921         guint pending_ops = 0;
1922  
1923         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1924         tmp = priv->progress_widgets;
1925
1926         /* Check all observers */
1927         while (tmp && is_empty)  {
1928                 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
1929                 is_empty = pending_ops == 0;
1930                 
1931                 tmp = g_slist_next(tmp);
1932         }
1933         
1934         return is_empty;
1935 }
1936
1937 static void
1938 on_queue_changed (ModestMailOperationQueue *queue,
1939                   ModestMailOperation *mail_op,
1940                   ModestMailOperationQueueNotification type,
1941                   ModestMainWindow *self)
1942 {
1943         ModestMainWindowPrivate *priv;
1944         ModestMailOperationTypeOperation op_type;
1945         ModestToolBarModes mode;
1946         GSList *tmp;
1947         gboolean mode_changed = FALSE;
1948 /*      ModestMailOperationStatus status; */
1949
1950         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1951         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1952                
1953         /* Get toolbar mode from operation id*/
1954         op_type = modest_mail_operation_get_type_operation (mail_op);
1955         switch (op_type) {
1956         case MODEST_MAIL_OPERATION_TYPE_SEND:
1957         case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
1958         case MODEST_MAIL_OPERATION_TYPE_OPEN:
1959                 mode = TOOLBAR_MODE_TRANSFER;
1960                 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
1961                         mode_changed = TRUE;
1962                 break;
1963         default:
1964                 mode = TOOLBAR_MODE_NORMAL;
1965                 
1966         }
1967                 
1968                        
1969         /* Add operation observers and change toolbar if neccessary*/
1970         tmp = priv->progress_widgets;
1971         switch (type) {
1972         case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
1973                 if (mode == TOOLBAR_MODE_TRANSFER) {
1974                         if (mode_changed)
1975                                 set_toolbar_transfer_mode(self);                    
1976                         while (tmp) {
1977                                 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1978                                                                       mail_op);
1979                                 tmp = g_slist_next (tmp);
1980                         }
1981                 }
1982                 break;
1983         case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED:
1984                 /* Change toolbar mode */
1985                 if (mode == TOOLBAR_MODE_TRANSFER) {                    
1986                         while (tmp) {
1987                                 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1988                                                                          mail_op);
1989                                 tmp = g_slist_next (tmp);
1990                         }
1991                         
1992                         /* If no more operations are being observed, NORMAL mode is enabled again */
1993                         if (observers_empty (self)) {
1994                                 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
1995                                 
1996                         }
1997                 }
1998
1999                 break;
2000         }       
2001
2002 }
2003
2004 static void 
2005 on_show_account_action_activated  (GtkAction *action,
2006                                    gpointer user_data)
2007 {
2008         ModestAccountData *acc_data;
2009         ModestMainWindow *self;
2010         ModestMainWindowPrivate *priv;
2011         ModestAccountMgr *mgr;
2012         const gchar *acc_name;
2013
2014         self = MODEST_MAIN_WINDOW (user_data);
2015         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2016
2017         /* Get account data */
2018         acc_name = gtk_action_get_name (action);
2019         mgr = modest_runtime_get_account_mgr ();
2020         acc_data = modest_account_mgr_get_account_data (mgr, acc_name);
2021
2022         /* Set the new visible & active account */
2023         if (acc_data->store_account) { 
2024                 modest_folder_view_set_account_id_of_visible_server_account (priv->folder_view,
2025                                                                              acc_data->store_account->account_name);
2026                 modest_window_set_active_account (MODEST_WINDOW (self), acc_data->account_name);
2027         }
2028
2029         /* Free */
2030         modest_account_mgr_free_account_data (mgr, acc_data);
2031 }
2032
2033 static void
2034 refresh_account (const gchar *account_name)
2035 {
2036         ModestWindow *win;
2037
2038         win = MODEST_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2039
2040         /* If account_name == NULL, we must update all (option All) */
2041         if (!account_name)
2042                 modest_ui_actions_do_send_receive_all (win);
2043         else
2044                 modest_ui_actions_do_send_receive (account_name, win);
2045         
2046 }
2047
2048 static void 
2049 on_refresh_account_action_activated  (GtkAction *action,
2050                                       gpointer user_data)
2051 {
2052         refresh_account ((const gchar*) user_data);
2053 }
2054
2055 static void
2056 on_send_receive_csm_activated (GtkMenuItem *item,
2057                                gpointer user_data)
2058 {
2059         refresh_account ((const gchar*) user_data);
2060 }
2061
2062 static gboolean
2063 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2064 {
2065         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2066
2067         hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2068         return FALSE;
2069
2070 }
2071
2072 static gboolean
2073 on_folder_view_focus_in (GtkWidget *widget,
2074                          GdkEventFocus *event,
2075                          gpointer userdata)
2076 {
2077         return FALSE;
2078 }
2079
2080 static gboolean
2081 on_header_view_focus_in (GtkWidget *widget,
2082                          GdkEventFocus *event,
2083                          gpointer userdata)
2084 {
2085         ModestMainWindow *main_window = MODEST_MAIN_WINDOW (userdata);
2086         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
2087
2088         if (modest_header_view_has_selected_headers (MODEST_HEADER_VIEW (priv->header_view))) {
2089                 TnyList *selection = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (priv->header_view));
2090                 TnyIterator *iterator = tny_list_create_iterator (selection);
2091                 TnyHeader *header;
2092
2093                 tny_iterator_first (iterator);
2094                 header = TNY_HEADER (tny_iterator_get_current (iterator));
2095                 
2096                 if (tny_header_get_subject (header))
2097                         gtk_window_set_title (GTK_WINDOW(main_window), tny_header_get_subject (header));
2098                 else
2099                         gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
2100
2101                 g_object_unref (header);
2102                 g_object_unref (iterator);
2103                 g_object_unref (selection);
2104         }
2105         return FALSE;
2106 }
2107
2108 static void 
2109 modest_main_window_on_folder_selection_changed (ModestFolderView *folder_view,
2110                                                 TnyFolderStore *folder_store, 
2111                                                 gboolean selected,
2112                                                 ModestMainWindow *main_window)
2113 {
2114         ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (main_window);
2115         GtkAction *action = NULL;
2116         gboolean show_reply = TRUE;
2117         gboolean show_forward = TRUE;
2118         gboolean show_cancel_send = FALSE;
2119         gboolean show_clipboard = TRUE;
2120         gboolean show_delete = TRUE;
2121
2122         if (selected) {
2123                 if (TNY_IS_ACCOUNT (folder_store)) {
2124                         show_reply = show_forward = show_cancel_send = show_clipboard = show_delete = FALSE;
2125                 } else if (TNY_IS_FOLDER (folder_store)) {
2126                         if (modest_tny_folder_is_local_folder (TNY_FOLDER (folder_store))) {
2127                                 TnyFolderType folder_type = modest_tny_folder_get_local_folder_type (
2128                                         TNY_FOLDER (folder_store));
2129                                 switch (folder_type) {
2130                                 case TNY_FOLDER_TYPE_DRAFTS:
2131                                         show_clipboard = show_delete = TRUE;
2132                                         show_reply = show_forward = show_cancel_send = FALSE;
2133                                         break;
2134                                 case TNY_FOLDER_TYPE_SENT:
2135                                         show_forward = show_clipboard = show_delete = TRUE;
2136                                         show_reply = show_cancel_send = FALSE;
2137                                         break;
2138                                 case TNY_FOLDER_TYPE_OUTBOX:
2139                                         show_clipboard = show_delete = show_cancel_send = TRUE;
2140                                         show_reply = show_forward = FALSE;
2141                                         break;
2142                                 default:
2143                                         show_reply = show_forward = show_clipboard = show_delete = TRUE;
2144                                         show_cancel_send = FALSE;
2145                                 }
2146                         } else {
2147                                 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2148                                 show_cancel_send = FALSE;
2149                         }
2150                 }
2151         }
2152
2153         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReply");
2154         gtk_action_set_visible (action, show_reply);
2155         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReplyAll");
2156         gtk_action_set_visible (action, show_reply);
2157         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMForward");
2158         gtk_action_set_visible (action, show_forward);
2159         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCancelSending");
2160         gtk_action_set_visible (action, show_cancel_send);
2161         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCut");
2162         gtk_action_set_visible (action, show_clipboard);
2163         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCopy");
2164         gtk_action_set_visible (action, show_clipboard);
2165         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMPaste");
2166         gtk_action_set_visible (action, show_clipboard);
2167         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMDelete");
2168         gtk_action_set_visible (action, show_delete);
2169
2170         /* We finally call to the ui actions handler, after updating properly
2171          * the header view CSM */
2172         modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window);
2173
2174 }