* Fixed a lot of reference leaks
[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 <tny-error.h>
38 #include "modest-hildon-includes.h"
39 #include "modest-defs.h"
40 #include <string.h>
41 #include "widgets/modest-header-view-priv.h"
42 #include "widgets/modest-main-window.h"
43 #include "widgets/modest-msg-edit-window.h"
44 #include "widgets/modest-account-view-window.h"
45 #include "modest-runtime.h"
46 #include "modest-account-mgr-helpers.h"
47 #include "modest-platform.h"
48 #include "modest-widget-memory.h"
49 #include "modest-window-priv.h"
50 #include "modest-main-window-ui.h"
51 #include "modest-main-window-ui-dimming.h"
52 #include "modest-account-mgr.h"
53 #include "modest-tny-account.h"
54 #include "modest-tny-folder.h"
55 #include "modest-conf.h"
56 #include <modest-utils.h>
57 #include <modest-maemo-utils.h>
58 #include "modest-tny-platform-factory.h"
59 #include "modest-tny-msg.h"
60 #include "modest-mail-operation.h"
61 #include "modest-icon-names.h"
62 #include "modest-progress-bar.h"
63 #include "modest-text-utils.h"
64 #include "modest-ui-dimming-manager.h"
65 #include "maemo/modest-osso-state-saving.h"
66 #include "modest-text-utils.h"
67 #include "modest-signal-mgr.h"
68
69 #define MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS "ModestMainWindowActionAdditions"
70
71 #define XALIGN 0.5
72 #define YALIGN 0.0
73 #define XSPACE 1
74 #define YSPACE 0
75
76 /* 'private'/'protected' functions */
77 static void modest_main_window_class_init  (ModestMainWindowClass *klass);
78 static void modest_main_window_init        (ModestMainWindow *obj);
79 static void modest_main_window_finalize    (GObject *obj);
80
81 static gboolean modest_main_window_window_state_event (GtkWidget *widget, 
82                                                        GdkEventWindowState *event, 
83                                                        gpointer userdata);
84
85 static void connect_signals (ModestMainWindow *self);
86
87 static void modest_main_window_disconnect_signals (ModestWindow *self);
88
89 static void restore_settings (ModestMainWindow *self, 
90                               gboolean do_folder_view_too);
91
92 static void save_state (ModestWindow *self);
93
94 static void update_menus (ModestMainWindow* self);
95
96 static void modest_main_window_show_toolbar   (ModestWindow *window,
97                                                gboolean show_toolbar);
98
99 static void cancel_progressbar (GtkToolButton *toolbutton,
100                                 ModestMainWindow *self);
101
102 static void on_queue_changed   (ModestMailOperationQueue *queue,
103                                 ModestMailOperation *mail_op,
104                                 ModestMailOperationQueueNotification type,
105                                 ModestMainWindow *self);
106
107 static gboolean on_zoom_minus_plus_not_implemented (ModestWindow *window);
108
109 static void on_account_inserted (TnyAccountStore *accoust_store,
110                                  TnyAccount *account,
111                                  gpointer user_data);
112
113 static void on_account_removed  (TnyAccountStore *accoust_store,
114                                  TnyAccount *account,
115                                  gpointer user_data);
116
117 static void on_account_changed  (TnyAccountStore *account_store,
118                                  TnyAccount *account,
119                                  gpointer user_data);
120
121 static void on_default_account_changed (ModestAccountMgr* mgr,
122                                         gpointer user_data);
123
124 static gboolean on_inner_widgets_key_pressed  (GtkWidget *widget,
125                                                GdkEventKey *event,
126                                                gpointer user_data);
127
128 static void on_configuration_key_changed      (ModestConf* conf, 
129                                                const gchar *key, 
130                                                ModestConfEvent event,
131                                                ModestConfNotificationId id,
132                                                ModestMainWindow *self);
133
134 static void set_toolbar_mode                  (ModestMainWindow *self, 
135                                                ModestToolBarModes mode);
136
137 static gboolean set_toolbar_transfer_mode     (ModestMainWindow *self); 
138
139 static void on_show_account_action_toggled      (GtkToggleAction *action,
140                                                  gpointer user_data);
141
142 static void on_refresh_account_action_activated   (GtkAction *action,
143                                                    gpointer user_data);
144
145 static void on_send_receive_csm_activated         (GtkMenuItem *item,
146                                                    gpointer user_data);
147
148 static void on_msg_count_changed (ModestHeaderView *header_view,
149                                   TnyFolder *folder,
150                                   TnyFolderChange *change,
151                                   ModestMainWindow *main_window);
152
153 static void modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self);
154
155
156 static GtkWidget * create_empty_view (void);
157
158 static gboolean  on_folder_view_focus_in (GtkWidget *widget,
159                                           GdkEventFocus *event,
160                                           gpointer userdata);
161
162 static gboolean  on_header_view_focus_in (GtkWidget *widget,
163                                           GdkEventFocus *event,
164                                           gpointer userdata);
165
166 static void      on_folder_selection_changed (ModestFolderView *folder_view,
167                                               TnyFolderStore *folder_store, 
168                                               gboolean selected,
169                                               ModestMainWindow *main_window);
170                                                 
171 static void set_at_least_one_account_visible(ModestMainWindow *self);
172
173 static void on_updating_msg_list (ModestHeaderView *header_view,
174                                   gboolean starting,
175                                   gpointer user_data);
176
177 static gboolean restore_paned_timeout_handler (gpointer *data);
178
179 static gboolean show_retrieving_banner (gpointer user_data);
180
181 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
182 struct _ModestMainWindowPrivate {
183         GtkWidget *msg_paned;
184         GtkWidget *main_paned;
185         GtkWidget *main_vbox;
186         GtkWidget *contents_widget;
187         GtkWidget *empty_view;
188
189         /* Progress observers */
190         GtkWidget   *progress_bar;
191         GSList      *progress_widgets;
192
193         /* Tollbar items */
194         GtkWidget   *progress_toolitem;
195         GtkWidget   *cancel_toolitem;
196         GtkWidget   *sort_toolitem;
197         GtkWidget   *refresh_toolitem;
198         ModestToolBarModes current_toolbar_mode;
199
200         /* Merge ids used to add/remove accounts to the ViewMenu*/
201         GByteArray *merge_ids;
202         GtkActionGroup *view_additions_group;
203
204         /* On-demand widgets */
205         GtkWidget *accounts_popup;
206         GtkWidget *details_widget;
207
208         /* Optimized view enabled */
209         gboolean optimized_view;
210
211         /* Optimized view enabled */
212         gboolean send_receive_in_progress;
213
214         ModestHeaderView *header_view;
215         ModestFolderView *folder_view;
216
217         ModestMainWindowStyle style;
218         ModestMainWindowContentsStyle contents_style;
219         gboolean wait_for_settings;
220
221         guint progress_bar_timeout;
222         guint restore_paned_timeout;
223
224         /* Signal handler UIDs */
225         GList *queue_err_signals;
226         GSList *sighandlers;
227
228         /* "Updating" banner for header view */
229         GtkWidget *updating_banner;
230         guint updating_banner_timeout;
231
232         /* "Retrieving" banner for header view */
233         GtkWidget *retrieving_banner;
234         guint retrieving_banner_timeout;
235
236         /* Display state */
237         osso_display_state_t display_state;
238 };
239 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
240                                                 MODEST_TYPE_MAIN_WINDOW, \
241                                                 ModestMainWindowPrivate))
242
243 typedef struct _GetMsgAsyncHelper {
244         ModestMainWindowPrivate *main_window_private;
245         guint action;
246         ModestTnyMsgReplyType reply_type;
247         ModestTnyMsgForwardType forward_type;
248         gchar *from;
249         TnyIterator *iter;
250 } GetMsgAsyncHelper;
251
252
253 /* globals */
254 static GtkWindowClass *parent_class = NULL;
255
256
257 /* Private actions */
258 /* This is the context sensitive menu: */
259 static const GtkActionEntry modest_folder_view_action_entries [] = {
260
261         /* Folder View CSM actions */
262         { "FolderViewCSMNewFolder", NULL, N_("mcen_ti_new_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
263         { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
264         { "FolderViewCSMPasteMsgs", NULL, N_("mcen_me_inbox_paste"), NULL, NULL,  G_CALLBACK (modest_ui_actions_on_paste)},
265         { "FolderViewCSMDeleteFolder", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
266         { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_search_messages) },
267         { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
268 };
269
270 static const GtkActionEntry modest_header_view_action_entries [] = {
271
272         /* Header View CSM actions */
273         { "HeaderViewCSMOpen",          NULL,  N_("mcen_me_inbox_open"),        NULL,       NULL, G_CALLBACK (modest_ui_actions_on_open) },
274         { "HeaderViewCSMReply",         NULL,  N_("mcen_me_inbox_reply"),       NULL,      NULL, G_CALLBACK (modest_ui_actions_on_reply) },
275         { "HeaderViewCSMReplyAll",      NULL,  N_("mcen_me_inbox_replytoall"),  NULL,      NULL, G_CALLBACK (modest_ui_actions_on_reply_all) },
276         { "HeaderViewCSMForward",       NULL,  N_("mcen_me_inbox_forward"),     NULL,      NULL, G_CALLBACK (modest_ui_actions_on_forward) },
277         { "HeaderViewCSMCut",           NULL,  N_("mcen_me_inbox_cut"),         "<CTRL>X", NULL, G_CALLBACK (modest_ui_actions_on_cut) },
278         { "HeaderViewCSMCopy",          NULL,  N_("mcen_me_inbox_copy"),        "<CTRL>C", NULL, G_CALLBACK (modest_ui_actions_on_copy) },
279         { "HeaderViewCSMPaste",         NULL,  N_("mcen_me_inbox_paste"),       "<CTRL>V", NULL, G_CALLBACK (modest_ui_actions_on_paste) },
280         { "HeaderViewCSMDelete",        NULL,  N_("mcen_me_inbox_delete"),      NULL,      NULL, G_CALLBACK (modest_ui_actions_on_delete_message) },
281         { "HeaderViewCSMCancelSending", NULL,  N_("mcen_me_outbox_cancelsend"), NULL,      NULL, G_CALLBACK (modest_ui_actions_cancel_send) },
282         { "HeaderViewCSMHelp",          NULL,  N_("mcen_me_inbox_help"),        NULL,      NULL, G_CALLBACK (modest_ui_actions_on_help) },
283 };
284
285 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
286         { "ToggleFolders",     MODEST_STOCK_SPLIT_VIEW, N_("mcen_me_inbox_hidefolders"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), TRUE },
287 };
288
289 /************************************************************************/
290
291 GType
292 modest_main_window_get_type (void)
293 {
294         static GType my_type = 0;
295         if (!my_type) {
296                 static const GTypeInfo my_info = {
297                         sizeof(ModestMainWindowClass),
298                         NULL,           /* base init */
299                         NULL,           /* base finalize */
300                         (GClassInitFunc) modest_main_window_class_init,
301                         NULL,           /* class finalize */
302                         NULL,           /* class data */
303                         sizeof(ModestMainWindow),
304                         1,              /* n_preallocs */
305                         (GInstanceInitFunc) modest_main_window_init,
306                         NULL
307                 };
308                 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
309                                                   "ModestMainWindow",
310                                                   &my_info, 0);
311         }
312         return my_type;
313 }
314
315 static void
316 modest_main_window_class_init (ModestMainWindowClass *klass)
317 {
318         GObjectClass *gobject_class;
319         gobject_class = (GObjectClass*) klass;
320         ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
321
322         parent_class            = g_type_class_peek_parent (klass);
323         gobject_class->finalize = modest_main_window_finalize;
324
325         g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
326         
327         modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
328         modest_window_class->save_state_func = save_state;
329         modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
330         modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
331         modest_window_class->disconnect_signals_func = modest_main_window_disconnect_signals;
332 }
333
334 static void
335 modest_main_window_init (ModestMainWindow *obj)
336 {
337         ModestMainWindowPrivate *priv;
338
339         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
340
341         priv->queue_err_signals = NULL;
342         priv->msg_paned    = NULL;
343         priv->main_paned   = NULL;      
344         priv->main_vbox    = NULL;
345         priv->header_view  = NULL;
346         priv->folder_view  = NULL;
347         priv->contents_widget  = NULL;
348         priv->accounts_popup  = NULL;
349         priv->details_widget  = NULL;
350         priv->empty_view  = NULL;
351         priv->progress_widgets  = NULL;
352         priv->progress_bar = NULL;
353         priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
354         priv->style  = MODEST_MAIN_WINDOW_STYLE_SPLIT;
355         priv->wait_for_settings = TRUE;
356         priv->contents_style  = -1; /* invalid contents style. We need this to select it for the first time */
357         priv->merge_ids = NULL;
358         priv->optimized_view  = FALSE;
359         priv->send_receive_in_progress  = FALSE;
360         priv->progress_bar_timeout = 0;
361         priv->restore_paned_timeout = 0;
362         priv->sighandlers = NULL;
363         priv->updating_banner = NULL;
364         priv->updating_banner_timeout = 0;
365         priv->retrieving_banner = NULL;
366         priv->retrieving_banner_timeout = 0;
367         priv->display_state = OSSO_DISPLAY_ON;
368         
369         modest_window_mgr_register_help_id (modest_runtime_get_window_mgr(),
370                                             GTK_WINDOW(obj),
371                                             "applications_email_mainview");
372 }
373
374 static void
375 modest_main_window_finalize (GObject *obj)
376 {
377         ModestMainWindowPrivate *priv;
378
379         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
380
381         /* Sanity check: shouldn't be needed, the window mgr should
382            call this function before */
383         modest_main_window_disconnect_signals (MODEST_WINDOW (obj));    
384         modest_main_window_cleanup_queue_error_signals ((ModestMainWindow *) obj);
385         
386         g_slist_free (priv->progress_widgets);
387
388         g_byte_array_free (priv->merge_ids, TRUE);
389
390         if (priv->progress_bar_timeout > 0) {
391                 g_source_remove (priv->progress_bar_timeout);
392                 priv->progress_bar_timeout = 0;
393         }
394
395         if (priv->updating_banner_timeout > 0) {
396                 g_source_remove (priv->updating_banner_timeout);
397                 priv->updating_banner_timeout = 0;
398         }
399
400         if (priv->updating_banner) {
401                 gtk_widget_destroy (priv->updating_banner);
402                 priv->updating_banner = NULL;
403         }
404
405         if (priv->retrieving_banner_timeout > 0) {
406                 g_source_remove (priv->retrieving_banner_timeout);
407                 priv->retrieving_banner_timeout = 0;
408         }
409
410         if (priv->retrieving_banner) {
411                 gtk_widget_destroy (priv->retrieving_banner);
412                 priv->retrieving_banner = NULL;
413         }
414
415         if (priv->restore_paned_timeout > 0) {
416                 g_source_remove (priv->restore_paned_timeout);
417                 priv->restore_paned_timeout = 0;
418         }
419         
420         G_OBJECT_CLASS(parent_class)->finalize (obj);
421 }
422
423 GtkWidget*
424 modest_main_window_get_child_widget (ModestMainWindow *self,
425                                      ModestMainWindowWidgetType widget_type)
426 {
427         ModestMainWindowPrivate *priv;
428         GtkWidget *widget;
429         
430         g_return_val_if_fail (self && MODEST_IS_MAIN_WINDOW(self), NULL);
431         g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_MAIN_WINDOW_WIDGET_TYPE_NUM,
432                               NULL);
433         
434         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
435
436         switch (widget_type) {
437         case MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW:
438                 widget = (GtkWidget*)priv->header_view; break;
439         case MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW:
440                 widget = (GtkWidget*)priv->folder_view; break;
441         default:
442                 return NULL;
443         }
444
445         return widget ? GTK_WIDGET(widget) : NULL;
446 }
447
448 static gboolean 
449 restore_paned_timeout_handler (gpointer *data)
450 {
451         ModestMainWindow *main_window = MODEST_MAIN_WINDOW (data);
452         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
453         ModestConf *conf;
454
455         /* Timeouts are outside the main lock */
456         gdk_threads_enter ();
457         if (GTK_WIDGET_VISIBLE (main_window)) {
458                 conf = modest_runtime_get_conf ();
459                 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
460                                               MODEST_CONF_MAIN_PANED_KEY);
461         }
462         gdk_threads_leave ();
463
464         return FALSE;
465 }
466
467
468 static void
469 restore_settings (ModestMainWindow *self, gboolean do_folder_view_too)
470 {
471         ModestConf *conf;
472         ModestMainWindowPrivate *priv;
473
474         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
475
476         conf = modest_runtime_get_conf ();
477
478         modest_widget_memory_restore (conf, G_OBJECT(self),
479                                       MODEST_CONF_MAIN_WINDOW_KEY);
480
481         modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
482                                       MODEST_CONF_HEADER_VIEW_KEY);
483
484         if (do_folder_view_too)
485                 modest_widget_memory_restore (conf, G_OBJECT(priv->folder_view),
486                                       MODEST_CONF_FOLDER_VIEW_KEY);
487
488 /*      modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned), */
489 /*                                    MODEST_CONF_MAIN_PANED_KEY); */
490
491         g_timeout_add (250, (GSourceFunc) restore_paned_timeout_handler, self);
492
493         /* We need to force a redraw here in order to get the right
494            position of the horizontal paned separator */
495         gtk_widget_show (GTK_WIDGET (self));
496 }
497
498
499 static void
500 save_state (ModestWindow *window)
501 {
502         ModestConf *conf;
503         ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
504         ModestMainWindowPrivate *priv;
505                 
506         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
507         conf = modest_runtime_get_conf ();
508         
509         modest_widget_memory_save (conf,G_OBJECT(self), 
510                                    MODEST_CONF_MAIN_WINDOW_KEY);
511         /* Only save main paned position if we're in split mode */
512         if (priv->style == MODEST_MAIN_WINDOW_STYLE_SPLIT)
513                 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned), 
514                                            MODEST_CONF_MAIN_PANED_KEY);
515         modest_widget_memory_save (conf, G_OBJECT(priv->folder_view), 
516                                    MODEST_CONF_FOLDER_VIEW_KEY);
517 }
518
519 static gint
520 compare_display_names (ModestAccountSettings *a,
521                        ModestAccountSettings *b)
522 {
523         return strcmp (modest_account_settings_get_display_name (a),
524                        modest_account_settings_get_display_name (b));
525 }
526
527 /* We use this function to prevent the send&receive CSM to be shown
528    when there are less than two account */
529 static gboolean
530 tap_and_hold_query_cb (GtkWidget *widget, GdkEvent *event)
531 {
532         return TRUE;
533 }
534
535 static void
536 update_menus (ModestMainWindow* self)
537 {       
538         GSList *account_names, *iter, *accounts;
539         ModestMainWindowPrivate *priv;
540         ModestWindowPrivate *parent_priv;
541         ModestAccountMgr *mgr;
542         gint i, num_accounts;
543         GList *groups;
544         gchar *default_account;
545         const gchar *active_account_name;
546         GtkWidget *send_receive_button, *item;
547         GtkAction *send_receive_all = NULL;
548         GSList *radio_group;
549
550         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
551         parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
552
553         /* Get enabled account IDs */
554         mgr = modest_runtime_get_account_mgr ();
555         account_names = modest_account_mgr_account_names (mgr, TRUE);
556         iter = account_names;
557         accounts = NULL;
558
559         while (iter) {
560                 ModestAccountSettings *settings = 
561                         modest_account_mgr_load_account_settings (mgr, (gchar*) iter->data);
562                 accounts = g_slist_prepend (accounts, settings);
563
564                 iter = iter->next;
565         }
566         modest_account_mgr_free_account_names (account_names);
567         account_names = NULL;
568
569         /* Order the list of accounts by its display name */
570         accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
571         num_accounts = g_slist_length (accounts);
572
573         send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager, 
574                                                       "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
575         gtk_action_set_visible (send_receive_all, num_accounts > 0);
576
577         /* Delete old send&receive popup items. We can not just do a
578            menu_detach because it does not work well with
579            tap_and_hold */
580         if (priv->accounts_popup)
581                 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup), 
582                                        (GtkCallback) gtk_widget_destroy, NULL);
583
584         /* Delete old entries in the View menu. Do not free groups, it
585            belongs to Gtk+ */
586         groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
587         while (groups) {
588                 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
589                              gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
590                         gtk_ui_manager_remove_action_group (parent_priv->ui_manager, 
591                                                             GTK_ACTION_GROUP (groups->data));
592                         groups = NULL;
593                         /* Remove uis */
594                         if (priv->merge_ids) {
595                                 for (i = 0; i < priv->merge_ids->len; i++)
596                                         gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
597                                 g_byte_array_free (priv->merge_ids, TRUE);
598                         }
599                         /* We need to call this in order to ensure
600                            that the new actions are added in the right
601                            order (alphabetical) */
602                         gtk_ui_manager_ensure_update (parent_priv->ui_manager);
603                 } else 
604                         groups = g_list_next (groups);
605         }
606         priv->merge_ids = g_byte_array_sized_new (num_accounts);
607
608         /* Get send receive button */
609         send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
610                                                           "/ToolBar/ToolbarSendReceive");
611
612         /* Create the menu */
613         if (num_accounts > 1) {
614                 if (!priv->accounts_popup)
615                         priv->accounts_popup = gtk_menu_new ();
616                 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
617                 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
618                 g_signal_connect (G_OBJECT (item), 
619                                   "activate", 
620                                   G_CALLBACK (on_send_receive_csm_activated),
621                                   NULL);
622                 item = gtk_separator_menu_item_new ();
623                 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
624         }
625
626         /* Create a new action group */
627         default_account = modest_account_mgr_get_default_account (mgr);
628         active_account_name = modest_window_get_active_account (MODEST_WINDOW (self));
629         
630         if (!active_account_name) 
631                 modest_window_set_active_account (MODEST_WINDOW (self), default_account);
632         
633         priv->view_additions_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
634         radio_group = NULL;
635         for (i = 0; i < num_accounts; i++) {
636                 gchar *display_name = NULL;     
637                 const gchar *account_name;
638                 ModestAccountSettings *settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
639
640                 if (!settings) {
641                         g_warning ("%s: BUG: account_data == NULL", __FUNCTION__);
642                         continue;
643                 }
644                 account_name = modest_account_settings_get_account_name (settings);
645         
646                 if (default_account && account_name && 
647                     !(strcmp (default_account, account_name) == 0)) {
648                         display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"), 
649                                                         modest_account_settings_get_display_name (settings));
650                 } else {
651                         display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"), 
652                                                         modest_account_settings_get_display_name (settings));
653                 }
654                 
655                 /* Create action and add it to the action group. The
656                    action name must be the account name, this way we
657                    could know in the handlers the account to show */
658                 if (settings && account_name) {
659                         gchar* item_name, *refresh_action_name;
660                         guint8 merge_id = 0;
661                         GtkAction *view_account_action, *refresh_account_action;
662
663                         view_account_action = GTK_ACTION (gtk_radio_action_new (account_name,
664                                                                                 display_name, NULL, NULL, 0));
665                         gtk_action_group_add_action (priv->view_additions_group, view_account_action);
666                         gtk_radio_action_set_group (GTK_RADIO_ACTION (view_account_action), radio_group);
667                         radio_group = gtk_radio_action_get_group (GTK_RADIO_ACTION (view_account_action));
668
669                         if (active_account_name) {
670                                 if (active_account_name && account_name && 
671                                     (strcmp (active_account_name, account_name) == 0)) {
672                                         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (view_account_action), TRUE);
673                                 }
674                         }
675
676                         /* Add ui from account data. We allow 2^9-1 account
677                            changes in a single execution because we're
678                            downcasting the guint to a guint8 in order to use a
679                            GByteArray. It should be enough. */
680                         item_name = g_strconcat (account_name, "Menu", NULL);
681                         merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
682                         priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
683                         gtk_ui_manager_add_ui (parent_priv->ui_manager,
684                                                merge_id,
685                                                "/MenuBar/ViewMenu/ViewMenuAdditions",
686                                                item_name,
687                                                account_name,
688                                                GTK_UI_MANAGER_MENUITEM,
689                                                FALSE);
690
691                         /* Connect the action signal "activate" */
692                         g_signal_connect_after (G_OBJECT (view_account_action),
693                                                 "toggled",
694                                                 G_CALLBACK (on_show_account_action_toggled),
695                                                 self);
696
697                         /* Create the items for the Tools->Send&Receive submenu */
698                         refresh_action_name = g_strconcat ("SendReceive", account_name, NULL);
699                         refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name, 
700                                                                  display_name, NULL, NULL);
701                         gtk_action_group_add_action (priv->view_additions_group, refresh_account_action);
702
703                         merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
704                         priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
705                         gtk_ui_manager_add_ui (parent_priv->ui_manager, 
706                                                merge_id,
707                                                "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
708                                                item_name,
709                                                refresh_action_name,
710                                                GTK_UI_MANAGER_MENUITEM,
711                                                FALSE);
712                         g_free (refresh_action_name);
713
714                         g_signal_connect_data (G_OBJECT (refresh_account_action), 
715                                                "activate", 
716                                                G_CALLBACK (on_refresh_account_action_activated), 
717                                                g_strdup (account_name),
718                                                (GClosureNotify) g_free,
719                                                0);
720
721                         /* Create item and add it to the send&receive
722                            CSM. If there is only one account then
723                            it'll be no menu */
724                         if (num_accounts > 1) {
725                                 GtkWidget *label = gtk_label_new(NULL);
726                                 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
727                                 if (default_account && (strcmp(account_name, default_account) == 0)) {
728                                         gchar *escaped = g_markup_printf_escaped ("<b>%s</b>", display_name);
729                                         gtk_label_set_markup (GTK_LABEL (label), escaped);
730                                         g_free (escaped);
731                                 } else {
732                                         gtk_label_set_text (GTK_LABEL (label), display_name);
733                                 }
734
735                                 item = gtk_menu_item_new ();
736                                 gtk_container_add (GTK_CONTAINER (item), label);
737
738                                 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
739                                 g_signal_connect_data (G_OBJECT (item), 
740                                                        "activate", 
741                                                        G_CALLBACK (on_send_receive_csm_activated),
742                                                        g_strdup (account_name),
743                                                        (GClosureNotify) g_free,
744                                                        0);
745                         }
746                         g_free (item_name);
747                 }
748
749                 /* Frees */
750                 g_free (display_name);
751         }
752
753         gtk_ui_manager_insert_action_group (parent_priv->ui_manager, priv->view_additions_group, 1);
754
755         /* We cannot do this in the loop above because this relies on the action
756          * group being inserted. This makes the default account appear in bold.
757          * I agree it is a rather ugly way, but I don't see another possibility. armin. */
758         for (i = 0; i < num_accounts; i++) {
759                 gchar *item_name, *path;
760                 GtkWidget *item;
761                 ModestAccountSettings *settings;
762                 const gchar *account_name;
763                 gboolean is_default;
764
765                 settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
766                 account_name = modest_account_settings_get_account_name (settings);
767                 is_default = (account_name && default_account && !strcmp (account_name, default_account));
768
769                 /* Get the item of the view menu */
770                 item_name = g_strconcat (account_name, "Menu", NULL);
771                 path = g_strconcat ("/MenuBar/ViewMenu/ViewMenuAdditions/", item_name, NULL);
772                 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
773                 g_free(path);
774                 
775                 if (item) {
776                         GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
777                         if (GTK_IS_LABEL (child)) {
778                                 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
779                                 if (is_default) {
780                                         gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
781                                         gtk_label_set_markup (GTK_LABEL (child), bold_name);
782                                         g_free (bold_name);
783                                 }
784                                 gtk_label_set_ellipsize (GTK_LABEL (child),  PANGO_ELLIPSIZE_END);
785                         }
786                 }
787                         
788                 /* Get the item of the tools menu */
789                 path = g_strconcat("/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions/", item_name, NULL);
790                 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
791                 g_free (path);
792
793                 if (item) {
794                         GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
795                         if (GTK_IS_LABEL (child)) {
796                                 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
797                                 if (is_default) {
798                                         gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
799                                         gtk_label_set_markup (GTK_LABEL (child), bold_name);
800                                         g_free (bold_name);
801                                 }
802                                 gtk_label_set_ellipsize (GTK_LABEL (child),  PANGO_ELLIPSIZE_END);
803                         }
804                 }
805
806                 g_free(item_name);
807                 g_object_unref (settings);
808         }
809
810         if (num_accounts > 1) {
811                 /* Disconnect the tap-and-hold-query if it's connected */
812                 if (modest_signal_mgr_is_connected (priv->sighandlers, 
813                                                     G_OBJECT (send_receive_button),
814                                                     "tap-and-hold-query"))
815                         priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers, 
816                                                                           G_OBJECT (send_receive_button),
817                                                                           "tap-and-hold-query");
818
819                 /* Mandatory in order to view the menu contents */
820                 gtk_widget_show_all (priv->accounts_popup);
821
822                 /* Setup tap_and_hold just if was not done before*/
823                 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
824                         gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
825         } else {
826                 /* Connect the tap-and-hold-query in order not to show the CSM */
827                 if (!modest_signal_mgr_is_connected (priv->sighandlers, 
828                                                      G_OBJECT (send_receive_button),
829                                                      "tap-and-hold-query"))
830                         priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, 
831                                                                        G_OBJECT (send_receive_button),
832                                                                        "tap-and-hold-query",
833                                                                        G_CALLBACK (tap_and_hold_query_cb), 
834                                                                        NULL);
835         }
836
837         /* Frees */
838         g_slist_free (accounts);
839         g_free (default_account);
840
841
842         /* Make sure that at least one account is viewed if there are any 
843          * accounts, for instance when adding the first account: */
844         set_at_least_one_account_visible (self);
845 }
846
847 static void
848 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
849 {
850         if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
851                 gtk_scrolled_window_add_with_viewport
852                         (GTK_SCROLLED_WINDOW(win), widget);
853         else
854                 gtk_container_add (GTK_CONTAINER(win),
855                                    widget);
856 }
857
858
859 typedef struct {
860         TnySendQueue *queue;
861         guint signal;
862 } QueueErrorSignal;
863
864 static void
865 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
866 {
867         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
868
869         GList *oerrsignals = priv->queue_err_signals;
870         while (oerrsignals) {
871                 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
872                 g_signal_handler_disconnect (esignal->queue, esignal->signal);
873                 g_slice_free (QueueErrorSignal, esignal);
874                 oerrsignals = g_list_next (oerrsignals);
875         }
876         g_list_free (priv->queue_err_signals);
877         priv->queue_err_signals = NULL;
878 }
879
880
881 static void
882 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
883 {
884         g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
885
886         /* Update dimmed */
887         modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
888 }
889
890 static void
891 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
892 {
893         g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
894
895         /* Update visibility */
896
897         /* Update dimmed */
898         modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
899 }
900
901 static void
902 modest_main_window_disconnect_signals (ModestWindow *self)
903 {       
904         ModestMainWindowPrivate *priv;  
905         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
906
907         modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
908         priv->sighandlers = NULL;       
909 }
910
911 static void
912 connect_signals (ModestMainWindow *self)
913 {       
914         ModestWindowPrivate *parent_priv;
915         ModestMainWindowPrivate *priv;
916         GtkWidget *menu;
917         
918         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
919         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
920
921         /* folder view */
922         
923         priv->sighandlers = 
924                 modest_signal_mgr_connect (priv->sighandlers,
925                                            G_OBJECT(priv->folder_view), "key-press-event",
926                                            G_CALLBACK(on_inner_widgets_key_pressed), self);
927         priv->sighandlers = 
928                 modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), 
929                                            "folder_selection_changed",
930                                            G_CALLBACK (on_folder_selection_changed), 
931                                            self);
932         priv->sighandlers = 
933                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view), 
934                                            "folder-display-name-changed",
935                                            G_CALLBACK (modest_ui_actions_on_folder_display_name_changed), 
936                                            self);
937         priv->sighandlers = 
938                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->folder_view), 
939                                            "focus-in-event", 
940                                            G_CALLBACK (on_folder_view_focus_in), 
941                                            self);
942
943         /* Folder view CSM */
944         menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
945         gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
946         priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), "tap-and-hold",
947                                                        G_CALLBACK(_folder_view_csm_menu_activated),
948                                                        self);
949         /* header view */
950         priv->sighandlers = 
951                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_selected",
952                                            G_CALLBACK(modest_ui_actions_on_header_selected), self);
953         priv->sighandlers = 
954                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_activated",
955                                            G_CALLBACK(modest_ui_actions_on_header_activated), self);
956         priv->sighandlers = 
957                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "item_not_found",
958                                            G_CALLBACK(modest_ui_actions_on_item_not_found), self);
959         priv->sighandlers = 
960                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "key-press-event",
961                                            G_CALLBACK(on_inner_widgets_key_pressed), self);
962         priv->sighandlers = 
963                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "msg_count_changed",
964                                            G_CALLBACK(on_msg_count_changed), self);
965         priv->sighandlers = 
966                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->header_view), "focus-in-event",
967                                            G_CALLBACK (on_header_view_focus_in), self);
968         priv->sighandlers = 
969                 modest_signal_mgr_connect (priv->sighandlers,
970                                            G_OBJECT (priv->header_view), 
971                                            "updating-msg-list",
972                                            G_CALLBACK (on_updating_msg_list), 
973                                            self);
974         
975         /* Header view CSM */
976         menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
977         gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
978         priv->sighandlers = 
979                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "tap-and-hold",
980                                            G_CALLBACK(_header_view_csm_menu_activated),
981                                            self);
982         
983         /* window */
984         priv->sighandlers = 
985                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (self), "window-state-event",
986                                            G_CALLBACK (modest_main_window_window_state_event),
987                                            NULL);
988
989         /* Mail Operation Queue */
990         priv->sighandlers = 
991                 modest_signal_mgr_connect (priv->sighandlers,
992                                            G_OBJECT (modest_runtime_get_mail_operation_queue ()),
993                                            "queue-changed", 
994                                            G_CALLBACK (on_queue_changed), self);
995         
996         /* Track changes in the device name */
997         priv->sighandlers = 
998                 modest_signal_mgr_connect (priv->sighandlers,
999                                            G_OBJECT(modest_runtime_get_conf ()),
1000                                            "key_changed", 
1001                                            G_CALLBACK (on_configuration_key_changed), 
1002                                            self);
1003         
1004         /* Track account changes. We need to refresh the toolbar */
1005         priv->sighandlers = 
1006                 modest_signal_mgr_connect (priv->sighandlers,
1007                                            G_OBJECT (modest_runtime_get_account_store ()),
1008                                            "account_inserted", 
1009                                            G_CALLBACK (on_account_inserted),
1010                                            self);
1011         priv->sighandlers = 
1012                 modest_signal_mgr_connect (priv->sighandlers,
1013                                            G_OBJECT (modest_runtime_get_account_store ()),
1014                                            "account_removed", 
1015                                            G_CALLBACK (on_account_removed),
1016                                            self);
1017
1018         /* We need to refresh the send & receive menu to change the bold
1019          * account when the default account changes. */
1020         priv->sighandlers = 
1021                 modest_signal_mgr_connect (priv->sighandlers,
1022                                            G_OBJECT (modest_runtime_get_account_mgr ()),
1023                                            "default_account_changed", 
1024                                            G_CALLBACK (on_default_account_changed),
1025                                            self);
1026
1027         /* Account store */
1028         priv->sighandlers = 
1029                 modest_signal_mgr_connect (priv->sighandlers,
1030                                            G_OBJECT (modest_runtime_get_account_store ()),
1031                                            "account_changed", 
1032                                            G_CALLBACK (on_account_changed),
1033                                            self);
1034
1035         priv->sighandlers = 
1036                 modest_signal_mgr_connect (priv->sighandlers,
1037                                            G_OBJECT (modest_runtime_get_account_store()), 
1038                                            "password_requested",
1039                                            G_CALLBACK (modest_ui_actions_on_password_requested), 
1040                                            self);
1041 }
1042
1043 static void 
1044 on_hildon_program_is_topmost_notify(GObject *self,
1045                                     GParamSpec *propert_param, 
1046                                     gpointer user_data)
1047 {
1048         HildonProgram *app = HILDON_PROGRAM (self);
1049         
1050         /* Note that use of hildon_program_set_can_hibernate() 
1051          * is generally referred to as "setting the killable flag", 
1052          * though hibernation does not seem equal to death.
1053          * murrayc */
1054                  
1055         if (hildon_program_get_is_topmost (app)) {
1056                 /* Prevent hibernation when the progam comes to the foreground,
1057                  * because hibernation should only happen when the application 
1058                  * is in the background: */
1059                 hildon_program_set_can_hibernate (app, FALSE);
1060
1061                 /* Remove new mail visual notifications */
1062                 modest_platform_remove_new_mail_notifications (TRUE);
1063         } else {
1064                 /* Allow hibernation if the program has gone to the background: */
1065                 
1066                 /* However, prevent hibernation while the settings are being changed: */
1067                 const gboolean hibernation_prevented = 
1068                         modest_window_mgr_get_hibernation_is_prevented (
1069                                                                         modest_runtime_get_window_mgr ()); 
1070         
1071                 if (hibernation_prevented)
1072                         hildon_program_set_can_hibernate (app, FALSE);
1073                 else {
1074                         /* Allow hibernation, after saving the state: */
1075                         modest_osso_save_state();
1076                         hildon_program_set_can_hibernate (app, TRUE);
1077                 }
1078         }       
1079 }
1080
1081 static void
1082 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
1083 {
1084         GtkWidget *folder_win = (GtkWidget *) user_data;
1085         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1086         
1087         priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
1088         wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
1089
1090         gtk_widget_show (GTK_WIDGET (priv->folder_view));
1091
1092         /* Connect signals */
1093         connect_signals (MODEST_MAIN_WINDOW (self));
1094
1095         /* Set account store */
1096         tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
1097                                                   TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1098
1099         /* Load previous osso state, for instance if we are being restored from 
1100          * hibernation:  */
1101         modest_osso_load_state ();
1102
1103         /* Restore window & widget settings */  
1104         priv->wait_for_settings = TRUE;
1105         restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
1106         priv->wait_for_settings = FALSE;
1107
1108         /* Check if accounts exist and show the account wizard if not */
1109         gboolean accounts_exist = 
1110                 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1111
1112         if (!accounts_exist) {
1113                 /* This is necessary to have the main window shown behind the dialog 
1114                 It's an ugly hack... jschmid */
1115                 gtk_widget_show_all(GTK_WIDGET(self));
1116                 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
1117         } else {
1118                 GSList *accounts;
1119                 GtkAction *send_receive_all;
1120                 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1121                 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
1122                 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager, 
1123                                                               "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1124                 gtk_action_set_visible (send_receive_all, g_slist_length (accounts) > 0);
1125                 modest_account_mgr_free_account_names (accounts);
1126                 update_menus (MODEST_MAIN_WINDOW (self));
1127         }
1128 }
1129
1130 static void 
1131 osso_display_event_cb (osso_display_state_t state, 
1132                        gpointer data)
1133 {
1134         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (data);
1135
1136         priv->display_state = state;
1137
1138         /* Stop blinking if the screen becomes on */
1139         if (priv->display_state == OSSO_DISPLAY_ON)
1140                 modest_platform_remove_new_mail_notifications (TRUE);
1141 }
1142
1143 ModestWindow *
1144 modest_main_window_new (void)
1145 {
1146         ModestMainWindow *self = NULL;  
1147         ModestMainWindowPrivate *priv = NULL;
1148         ModestWindowPrivate *parent_priv = NULL;
1149         GtkWidget *folder_win = NULL;
1150         ModestDimmingRulesGroup *menu_rules_group = NULL;
1151         ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1152         GtkActionGroup *action_group = NULL;
1153         GError *error = NULL;
1154         HildonProgram *app;
1155         ModestConf *conf = NULL;
1156         GtkAction *action = NULL;
1157         GdkPixbuf *window_icon;
1158         
1159         self  = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
1160         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1161         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1162
1163         parent_priv->ui_manager = gtk_ui_manager_new();
1164         parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
1165
1166         action_group = gtk_action_group_new ("ModestMainWindowActions");
1167         gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
1168
1169         menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1170         toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1171
1172         /* Add common actions */
1173         gtk_action_group_add_actions (action_group,
1174                                       modest_action_entries,
1175                                       G_N_ELEMENTS (modest_action_entries),
1176                                       self);
1177
1178         gtk_action_group_add_actions (action_group,
1179                                       modest_folder_view_action_entries,
1180                                       G_N_ELEMENTS (modest_folder_view_action_entries),
1181                                       self);
1182
1183         gtk_action_group_add_actions (action_group,
1184                                       modest_header_view_action_entries,
1185                                       G_N_ELEMENTS (modest_header_view_action_entries),
1186                                       self);
1187
1188         gtk_action_group_add_toggle_actions (action_group,
1189                                              modest_toggle_action_entries,
1190                                              G_N_ELEMENTS (modest_toggle_action_entries),
1191                                              self);
1192
1193         gtk_action_group_add_toggle_actions (action_group,
1194                                              modest_main_window_toggle_action_entries,
1195                                              G_N_ELEMENTS (modest_main_window_toggle_action_entries),
1196                                              self);
1197
1198         gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
1199         g_object_unref (action_group);
1200
1201         /* Load the UI definition */
1202         gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
1203                                          MODEST_UIDIR "modest-main-window-ui.xml", &error);
1204         if (error != NULL) {
1205                 g_warning ("Could not merge modest-ui.xml: %s", error->message);
1206                 g_error_free (error);
1207                 error = NULL;
1208         }
1209
1210         /* Add common dimming rules */
1211         modest_dimming_rules_group_add_rules (menu_rules_group, 
1212                                               modest_main_window_menu_dimming_entries,
1213                                               G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
1214                                               MODEST_WINDOW (self));
1215         modest_dimming_rules_group_add_rules (toolbar_rules_group, 
1216                                               modest_main_window_toolbar_dimming_entries,
1217                                               G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
1218                                               MODEST_WINDOW (self));
1219
1220         /* Insert dimming rules group for this window */
1221         modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1222         modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1223         g_object_unref (menu_rules_group);
1224         g_object_unref (toolbar_rules_group);
1225         
1226         /* Add accelerators */
1227         gtk_window_add_accel_group (GTK_WINDOW (self), 
1228                                     gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
1229
1230         /* Menubar. Update the state of some toggles */
1231         parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1232         conf = modest_runtime_get_conf ();
1233         action = gtk_ui_manager_get_action (parent_priv->ui_manager, 
1234                                             "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
1235         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1236                                       modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR, NULL));
1237         action = gtk_ui_manager_get_action (parent_priv->ui_manager, 
1238                                             "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
1239         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1240                                       modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
1241         hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
1242         gtk_widget_show (parent_priv->menubar);
1243
1244         /* Get device name */
1245         modest_maemo_utils_get_device_name ();
1246
1247         /* header view */
1248         priv->header_view =
1249                 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
1250         if (!priv->header_view)
1251                 g_printerr ("modest: cannot instantiate header view\n");
1252         modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
1253         modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
1254                                       MODEST_CONF_HEADER_VIEW_KEY);
1255
1256         /* Other style properties of header view */
1257         g_object_set (G_OBJECT (priv->header_view), 
1258                       "rules-hint", FALSE,
1259                       NULL);
1260         /* gtk_widget_show (priv->header_view); */
1261
1262         /* Empty view */ 
1263         priv->empty_view = create_empty_view ();
1264         gtk_widget_show (priv->empty_view);
1265                  
1266         /* Create scrolled windows */
1267         folder_win = gtk_scrolled_window_new (NULL, NULL);
1268         priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
1269         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
1270                                         GTK_POLICY_NEVER,
1271                                         GTK_POLICY_AUTOMATIC);
1272         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
1273                                         GTK_POLICY_NEVER,
1274                                         GTK_POLICY_AUTOMATIC);
1275         /* gtk_widget_show (priv->contents_widget); */
1276
1277         /* paned */
1278         priv->main_paned = gtk_hpaned_new ();
1279         gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
1280         gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
1281         gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
1282
1283         /* putting it all together... */
1284         priv->main_vbox = gtk_vbox_new (FALSE, 6);
1285         gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
1286         gtk_widget_show (priv->main_vbox);
1287         
1288         gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
1289         
1290         app = hildon_program_get_instance ();
1291         hildon_program_add_window (app, HILDON_WINDOW (self));
1292         
1293         g_signal_connect (G_OBJECT(app), "notify::is-topmost",
1294                 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
1295
1296         g_signal_connect (G_OBJECT(self), "show",
1297                           G_CALLBACK (modest_main_window_on_show), folder_win);
1298                 
1299         /* Set window icon */
1300         window_icon = modest_platform_get_icon (MODEST_APP_ICON, MODEST_ICON_SIZE_BIG);
1301         if (window_icon) {
1302                 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
1303                 g_object_unref (window_icon);
1304         }
1305
1306         /* Listen for changes in the screen, we don't want to show a
1307            led pattern when the display is on for example */
1308         osso_hw_set_display_event_cb (modest_maemo_utils_get_osso_context (),
1309                                       osso_display_event_cb,
1310                                       self); 
1311
1312         /* Dont't restore settings here, 
1313          * because it requires a gtk_widget_show(), 
1314          * and we don't want to do that until later,
1315          * so that the UI is not visible for non-menu D-Bus activation.
1316          */
1317
1318         return MODEST_WINDOW(self);
1319 }
1320
1321 void 
1322 modest_main_window_set_style (ModestMainWindow *self, 
1323                               ModestMainWindowStyle style)
1324 {
1325         ModestMainWindowPrivate *priv;
1326         ModestWindowPrivate *parent_priv;
1327         GtkAction *action;
1328         gboolean active;
1329
1330         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1331
1332         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1333         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1334
1335         /* no change -> nothing to do */
1336         if (priv->style == style)
1337                 return;
1338
1339        /* Get toggle button and update the state if needed. This will
1340           happen only when the set_style is not invoked from the UI,
1341           for example when it's called from widget memory */
1342        action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1343        active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
1344        if ((active && style == MODEST_MAIN_WINDOW_STYLE_SIMPLE) ||
1345            (!active && style == MODEST_MAIN_WINDOW_STYLE_SPLIT)) {
1346                g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1347                gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), !active);
1348                g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1349        }
1350
1351         priv->style = style;
1352         switch (style) {
1353         case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
1354
1355                 if (!priv->wait_for_settings)
1356                         modest_widget_memory_save (modest_runtime_get_conf (), G_OBJECT (priv->main_paned),
1357                                                    MODEST_CONF_MAIN_PANED_KEY);
1358                 /* Remove main paned */
1359                 g_object_ref (priv->main_paned);
1360                 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1361
1362                 /* Reparent the contents widget to the main vbox */
1363                 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
1364
1365                 break;
1366         case MODEST_MAIN_WINDOW_STYLE_SPLIT:
1367                 /* Remove header view */
1368                 g_object_ref (priv->contents_widget);
1369                 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
1370
1371                 /* Reparent the main paned */
1372                 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
1373                 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1374
1375                 g_timeout_add (500, (GSourceFunc) restore_paned_timeout_handler, self);
1376
1377                 break;
1378         default:
1379                 g_return_if_reached ();
1380         }
1381
1382         /* Let header view grab the focus if it's being shown */
1383         if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1384                 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1385         else 
1386                 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1387
1388         /* Show changes */
1389         gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1390 }
1391
1392 ModestMainWindowStyle
1393 modest_main_window_get_style (ModestMainWindow *self)
1394 {
1395         ModestMainWindowPrivate *priv;
1396
1397         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1398
1399         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1400         return priv->style;
1401 }
1402
1403 static void
1404 toolbar_resize (ModestMainWindow *self)
1405 {
1406         ModestMainWindowPrivate *priv = NULL;
1407         ModestWindowPrivate *parent_priv = NULL;
1408         GtkWidget *widget;
1409         gint static_button_size;
1410         ModestWindowMgr *mgr;
1411
1412         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1413         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1414         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1415
1416         mgr = modest_runtime_get_window_mgr ();
1417         static_button_size = modest_window_mgr_get_fullscreen_mode (mgr)?118:108;
1418
1419         if (parent_priv->toolbar) {
1420                 /* left size buttons */
1421                 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageNew");
1422                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1423                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1424                 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1425                 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply");
1426                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1427                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1428                 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1429                 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage");
1430                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1431                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1432                 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1433                 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1434                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1435                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1436                 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1437                 
1438                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1439                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1440                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1441                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1442                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1443                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1444                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1445                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1446         }
1447                 
1448 }
1449
1450
1451
1452 static gboolean
1453 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1454 {
1455         if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1456                 ModestWindowPrivate *parent_priv;
1457                 ModestWindowMgr *mgr;
1458                 gboolean is_fullscreen;
1459                 GtkAction *fs_toggle_action;
1460                 gboolean active;
1461                 
1462                 mgr = modest_runtime_get_window_mgr ();
1463                 
1464                 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1465
1466                 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1467                 
1468                 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1469                 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1470                 if (is_fullscreen != active) {
1471                         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1472                 }
1473
1474                 toolbar_resize (MODEST_MAIN_WINDOW (widget));
1475         }
1476
1477         return FALSE;
1478
1479 }
1480
1481 static void 
1482 modest_main_window_show_toolbar (ModestWindow *self,
1483                                  gboolean show_toolbar)
1484 {
1485         ModestMainWindowPrivate *priv = NULL;
1486         ModestWindowPrivate *parent_priv = NULL;        
1487         GtkWidget *reply_button = NULL, *menu = NULL;
1488         GtkWidget *placeholder = NULL;
1489         gint insert_index;
1490         const gchar *action_name;
1491         GtkAction *action;
1492
1493         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1494         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1495         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1496
1497         /* Set optimized view status */
1498         priv->optimized_view = !show_toolbar;
1499
1500         if (!parent_priv->toolbar) {
1501                 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
1502                                                                   "/ToolBar");
1503                 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1504
1505                 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1506                 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1507                 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1508                 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1509                 toolbar_resize (MODEST_MAIN_WINDOW (self));
1510                 
1511                 /* Add ProgressBar (Transfer toolbar) */ 
1512                 priv->progress_bar = modest_progress_bar_new ();
1513                 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1514                 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1515                 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1516                 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1517                 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1518                 
1519                 /* Connect cancel 'clicked' signal to abort progress mode */
1520                 g_signal_connect(priv->cancel_toolitem, "clicked",
1521                                  G_CALLBACK(cancel_progressbar),
1522                                  self);
1523                 
1524                 /* Add it to the observers list */
1525                 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1526
1527                 /* Add to window */
1528                 hildon_window_add_toolbar (HILDON_WINDOW (self), 
1529                                            GTK_TOOLBAR (parent_priv->toolbar));
1530
1531                 /* Set reply button tap and hold menu */
1532                 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
1533                                                           "/ToolBar/ToolbarMessageReply");
1534                 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1535                                                   "/ToolbarReplyCSM");
1536                 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1537
1538                 /* Set send & receive button tap and hold menu */
1539                 update_menus (MODEST_MAIN_WINDOW (self));
1540         }
1541         
1542         if (show_toolbar) {
1543                 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */ 
1544                 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1545                 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1546
1547                 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1548                 if (modest_main_window_transfer_mode_enabled (MODEST_MAIN_WINDOW(self)))
1549                         set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_TRANSFER);
1550                 else
1551                         set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1552         } else {
1553                 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1554
1555         }
1556
1557         /* Update also the actions (to update the toggles in the
1558            menus), we have to do it manually because some other window
1559            of the same time could have changed it (remember that the
1560            toolbar fullscreen mode is shared by all the windows of the
1561            same type */
1562         if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
1563                 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu";
1564         else
1565                 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu";
1566
1567         action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
1568         modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
1569                                                             show_toolbar);
1570 }
1571
1572 static void
1573 on_account_inserted (TnyAccountStore *accoust_store,
1574                      TnyAccount *account,
1575                      gpointer user_data)
1576 {
1577         /* Transport accounts and local ones (MMC and the Local
1578            folders account do now cause menu changes */
1579         if (TNY_IS_STORE_ACCOUNT (account) && 
1580             modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1581                 update_menus (MODEST_MAIN_WINDOW (user_data));
1582 }
1583
1584 static void
1585 on_default_account_changed (ModestAccountMgr* mgr,
1586                             gpointer user_data)
1587 {
1588         update_menus (MODEST_MAIN_WINDOW (user_data));
1589 }
1590
1591 static void
1592 on_account_removed (TnyAccountStore *accoust_store,
1593                      TnyAccount *account,
1594                      gpointer user_data)
1595 {
1596         /* Transport accounts and local ones (MMC and the Local
1597            folders account do now cause menu changes */
1598         if (TNY_IS_STORE_ACCOUNT (account) && 
1599             modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1600                 update_menus (MODEST_MAIN_WINDOW (user_data));
1601 }
1602
1603 static void
1604 on_account_changed (TnyAccountStore *account_store,
1605                     TnyAccount *account,
1606                     gpointer user_data)
1607 {
1608         ModestMainWindow *win = MODEST_MAIN_WINDOW (user_data);
1609         
1610         /* We need to refresh the details widget because it could have changed */
1611         if (modest_main_window_get_contents_style(win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS) {
1612                 modest_main_window_set_contents_style (win, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1613         }
1614
1615         /* Update the menus as well, the account name could be
1616            changed. Transport accounts and local ones (MMC and the
1617            Local folders account do now cause menu changes */
1618         if (TNY_IS_STORE_ACCOUNT (account) && 
1619             modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1620                 update_menus (MODEST_MAIN_WINDOW (user_data));
1621 }
1622
1623 /* 
1624  * This function manages the key events used to navigate between
1625  * header and folder views (when the window is in split view)
1626  *
1627  * FROM         KEY        ACTION
1628  * -------------------------------------------------
1629  * HeaderView   GDK_Left   Move focus to folder view
1630  * FolderView   GDK_Right  Move focus to header view
1631  *
1632  * There is no need to scroll to selected row, the widgets will be the
1633  * responsibles of doing that (probably managing the focus-in event
1634  */
1635 static gboolean 
1636 on_inner_widgets_key_pressed (GtkWidget *widget,
1637                               GdkEventKey *event,
1638                               gpointer user_data)
1639 {
1640         ModestMainWindowPrivate *priv;
1641
1642         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1643
1644         /* Do nothing if we're in SIMPLE style */
1645         if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1646                 return FALSE;
1647
1648         if (MODEST_IS_HEADER_VIEW (widget)) {
1649                 if (event->keyval == GDK_Left)
1650                         gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1651                 else if ((event->keyval == GDK_Return)||(event->keyval == GDK_KP_Enter)) {
1652                         guint selected_headers = modest_header_view_count_selected_headers (MODEST_HEADER_VIEW (widget));
1653                         if (selected_headers > 1) {
1654                                 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1655                                 return TRUE;
1656                         }
1657                 }
1658         } else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1659                 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1660
1661         return FALSE;
1662 }
1663
1664 static void
1665 set_alignment (GtkWidget *widget,
1666                gpointer data)
1667 {
1668         gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1669         gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1670 }
1671
1672 static GtkWidget *
1673 create_empty_view (void)
1674 {
1675         GtkLabel *label = NULL;
1676         GtkWidget *align = NULL;
1677
1678         align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1679         label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1680         gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);      
1681         gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1682
1683         return GTK_WIDGET(align);
1684 }
1685
1686 /*
1687  * Free the returned string
1688  */
1689 static gchar *
1690 get_gray_color_markup (GtkWidget *styled_widget)
1691 {
1692         gchar *gray_color_markup = NULL;
1693 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1694         /* Obtain the secondary text color. We need a realized widget, that's why 
1695            we get styled_widget from outside */
1696         GdkColor color;
1697         if (gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color)) 
1698                 gray_color_markup = modest_text_utils_get_color_string (&color);
1699 #endif /*MODEST_HAVE_HILDON0_WIDGETS*/
1700         
1701         if (!gray_color_markup) 
1702                 gray_color_markup = g_strdup ("#BBBBBB");
1703
1704         return gray_color_markup;
1705 }
1706
1707 /*
1708  * Free the returned string
1709  */
1710 static gchar*
1711 create_device_name_visual_string (const gchar *device_name,
1712                                   const gchar *gray_color_markup)
1713 {
1714         gchar *tmp, *label;
1715
1716         /* We have to use "" to fill the %s of the translation. We can
1717            not just use the device name because the device name is
1718            shown in a different color, so it could not be included
1719            into the <span> tag */
1720         tmp = g_strdup_printf (_("mcen_fi_localroot_description"), "");
1721         label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s", 
1722                                          gray_color_markup, 
1723                                          tmp, 
1724                                          device_name);
1725         g_free (tmp);
1726
1727         return label;
1728 }
1729
1730 static GtkWidget *
1731 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1732 {
1733         /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1734         
1735         GtkWidget *vbox;
1736         GtkWidget *label_w;
1737         gchar *label;
1738         gchar *gray_color_markup;
1739
1740         vbox = gtk_vbox_new (FALSE, 0);
1741
1742         gray_color_markup = get_gray_color_markup (styled_widget);
1743
1744         /* Account description: */
1745         if (modest_tny_account_is_virtual_local_folders (account)
1746                 || (modest_tny_account_is_memory_card_account (account))) {
1747         
1748                 /* Get device name */
1749                 gchar *device_name = NULL;
1750                 if (modest_tny_account_is_virtual_local_folders (account))
1751                         device_name = modest_conf_get_string (modest_runtime_get_conf(),
1752                                                       MODEST_CONF_DEVICE_NAME, NULL);
1753                 else
1754                         device_name = g_strdup (tny_account_get_name (account));
1755
1756                 label = create_device_name_visual_string ((const gchar *) device_name, 
1757                                                           (const gchar *) gray_color_markup);
1758                 label_w = gtk_label_new (NULL);
1759                 gtk_label_set_markup (GTK_LABEL (label_w), label);
1760                 gtk_label_set_ellipsize (GTK_LABEL (label_w),  PANGO_ELLIPSIZE_END);
1761                 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1762                 g_free (device_name);
1763                 g_free (label);
1764         } else {
1765                 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1766                         gtk_box_pack_start (GTK_BOX (vbox), 
1767                                 gtk_label_new (tny_account_get_name (account)), 
1768                                 FALSE, FALSE, 0);
1769                 } else {
1770                         /* Other accounts, such as IMAP and POP: */
1771                         
1772                         GString *proto;
1773                         gchar *tmp;
1774         
1775                         /* Put proto in uppercase */
1776                         proto = g_string_new (tny_account_get_proto (account));
1777                         proto = g_string_ascii_up (proto);
1778                         
1779                         /* note: mcen_fi_localroot_description is something like "%s account"
1780                          * however, we should display "%s account: %s"... therefore, ugly tmp */
1781                         tmp   = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1782                         label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s", 
1783                                                          gray_color_markup, tmp, tny_account_get_name (account));
1784                         g_free (tmp);
1785
1786                         label_w = gtk_label_new (NULL);
1787                         gtk_label_set_markup (GTK_LABEL (label_w), label);
1788                         gtk_label_set_ellipsize (GTK_LABEL (label_w),  PANGO_ELLIPSIZE_END);
1789                         gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1790                         g_string_free (proto, TRUE);
1791                         g_free (label);
1792                 }
1793         }
1794
1795         /* Message count */
1796         TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1797         label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d", 
1798                                          gray_color_markup, _("mcen_fi_rootfolder_messages"), 
1799                                          modest_tny_folder_store_get_message_count (folder_store));
1800         label_w = gtk_label_new (NULL);
1801         gtk_label_set_markup (GTK_LABEL (label_w), label);
1802         gtk_label_set_ellipsize (GTK_LABEL (label_w),  PANGO_ELLIPSIZE_END);
1803         gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1804         g_free (label);
1805
1806         /* Folder count */
1807         label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d", 
1808                                          gray_color_markup, 
1809                                          _("mcen_fi_rootfolder_folders"), 
1810                                          modest_tny_folder_store_get_folder_count (folder_store));
1811         label_w = gtk_label_new (NULL);
1812         gtk_label_set_markup (GTK_LABEL (label_w), label);
1813         gtk_label_set_ellipsize (GTK_LABEL (label_w),  PANGO_ELLIPSIZE_END);
1814         gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1815         g_free (label);
1816
1817         /* Size / Date */
1818         if (modest_tny_account_is_virtual_local_folders (account)
1819                 || modest_tny_account_is_memory_card_account (account)) {
1820
1821                 gchar *size = modest_text_utils_get_display_size (
1822                         modest_tny_folder_store_get_local_size (folder_store));
1823                 
1824                 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s", 
1825                                                  gray_color_markup, _("mcen_fi_rootfolder_size"),
1826                                                  size);
1827                 g_free (size);
1828                 
1829                 label_w = gtk_label_new (NULL);
1830                 gtk_label_set_markup (GTK_LABEL (label_w), label);
1831                 gtk_label_set_ellipsize (GTK_LABEL (label_w),  PANGO_ELLIPSIZE_END);
1832                 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1833                 g_free (label);
1834         } else if (TNY_IS_ACCOUNT(folder_store)) {
1835                 TnyAccount *account = TNY_ACCOUNT(folder_store);
1836                 
1837                 time_t last_updated;
1838                 const gchar *last_updated_string;
1839                 /* Get last updated from configuration */
1840                 last_updated = modest_account_mgr_get_last_updated (modest_runtime_get_account_mgr (), 
1841                                                                     tny_account_get_id (account));
1842
1843                 if (last_updated > 0) 
1844                         last_updated_string = modest_text_utils_get_display_date(last_updated);
1845                 else
1846                         last_updated_string = g_strdup (_("mcen_va_never"));
1847
1848                 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s", 
1849                                                  gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1850                 label_w = gtk_label_new (NULL);
1851                 gtk_label_set_markup (GTK_LABEL (label_w), label);
1852                 gtk_label_set_ellipsize (GTK_LABEL (label_w),  PANGO_ELLIPSIZE_END);
1853                 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1854                 g_free (label);
1855         }
1856
1857         g_free (gray_color_markup);
1858
1859         /* Set alignment */
1860         gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1861
1862         return vbox;
1863 }
1864
1865 gboolean
1866 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1867 {
1868         ModestMainWindowPrivate *priv = NULL;
1869         
1870         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1871
1872         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1873
1874         return priv->send_receive_in_progress;
1875 }
1876
1877 void 
1878 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1879 {
1880         GtkAction *action = NULL;
1881         GtkWidget *widget = NULL;
1882         ModestMainWindowPrivate *priv = NULL;
1883                 
1884         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1885         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1886         
1887         priv->send_receive_in_progress  = TRUE;
1888
1889         action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu"); 
1890         gtk_action_set_sensitive (action, FALSE);
1891 /*         action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1892 /*      gtk_action_set_sensitive (action, FALSE); */
1893         widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");       
1894         gtk_widget_set_sensitive (widget, FALSE);
1895
1896
1897 void 
1898 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1899 {
1900         GtkAction *action = NULL;
1901         GtkWidget *widget = NULL;
1902         ModestMainWindowPrivate *priv = NULL;
1903                 
1904         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1905         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1906
1907         priv->send_receive_in_progress  = FALSE;
1908
1909         action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu"); 
1910         gtk_action_set_sensitive (action, TRUE);
1911 /*         action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu");     */
1912 /*      gtk_action_set_sensitive (action, TRUE); */
1913         widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");       
1914         gtk_widget_set_sensitive (widget, TRUE);
1915
1916
1917
1918 static void
1919 on_msg_count_changed (ModestHeaderView *header_view,
1920                       TnyFolder *folder,
1921                       TnyFolderChange *change,
1922                       ModestMainWindow *main_window)
1923 {
1924         gboolean refilter = FALSE;
1925         gboolean folder_empty = FALSE;
1926         gboolean all_marked_as_deleted = FALSE;
1927         ModestMainWindowPrivate *priv;
1928
1929         g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1930         g_return_if_fail (TNY_IS_FOLDER(folder));
1931         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
1932
1933         if (change != NULL) {
1934                 TnyFolderChangeChanged changed;
1935
1936                 changed = tny_folder_change_get_changed (change);
1937                 /* If something changes */
1938                 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1939                         folder_empty = (((guint) tny_folder_change_get_new_all_count (change)) == 0);
1940                 else
1941                         folder_empty = (((guint) tny_folder_get_all_count (TNY_FOLDER (folder))) == 0);
1942
1943                 /* Play a sound (if configured) and make the LED blink  */
1944                 if (changed & TNY_FOLDER_CHANGE_CHANGED_ADDED_HEADERS) {
1945                         modest_platform_push_email_notification ();
1946                 }
1947
1948                 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_EXPUNGED_HEADERS)
1949                         refilter = TRUE;
1950         } else {
1951                 folder_empty = (((guint) tny_folder_get_all_count (TNY_FOLDER (folder))) == 0);
1952         }
1953
1954         /* Check if all messages are marked to be deleted */
1955         all_marked_as_deleted = modest_header_view_is_empty (header_view);
1956         folder_empty = folder_empty || all_marked_as_deleted;
1957
1958         /* Set contents style of headers view */
1959         if (folder_empty)  {
1960                 modest_main_window_set_contents_style (main_window,
1961                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1962                 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1963         } else {
1964                 modest_main_window_set_contents_style (main_window,
1965                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1966         }
1967
1968         if (refilter)
1969                 modest_header_view_refilter (header_view);
1970 }
1971
1972
1973 void 
1974 modest_main_window_set_contents_style (ModestMainWindow *self, 
1975                                        ModestMainWindowContentsStyle style)
1976 {
1977         ModestMainWindowPrivate *priv;
1978
1979         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1980
1981         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1982
1983         /* We allow to set the same content style than the previously
1984            set if there are details, because it could happen when we're
1985            selecting different accounts consecutively */
1986         if ((priv->contents_style == style) &&
1987             (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1988                 return;
1989
1990         /* Remove previous child. Delete it if it was an account
1991            details widget */
1992         GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1993         if (content) {
1994                 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1995                         g_object_ref (content);
1996                 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1997                         g_object_ref (priv->empty_view);
1998                         gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
1999                 }
2000                 
2001                 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
2002         }
2003
2004         priv->contents_style = style;
2005
2006         switch (priv->contents_style) {
2007         case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
2008                 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
2009                 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2010                                                       TRUE);
2011                 break;
2012         case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
2013         {
2014                 /* if we're started without main win, there may not be a folder
2015                  * view. this fixes a GLib-Critical */
2016                 if (priv->folder_view) {
2017                         TnyFolderStore *selected_folderstore = 
2018                                 modest_folder_view_get_selected (priv->folder_view);
2019                         if (TNY_IS_ACCOUNT (selected_folderstore)) {    
2020                                 priv->details_widget = create_details_widget (GTK_WIDGET (self),
2021                                                                 TNY_ACCOUNT (selected_folderstore));
2022                                 
2023                                 wrap_in_scrolled_window (priv->contents_widget, 
2024                                                          priv->details_widget);
2025                         }
2026                         g_object_unref (selected_folderstore);
2027                         modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2028                                                               FALSE);
2029                 }
2030                 break;
2031         }
2032         case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
2033                 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
2034                 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2035                                                       FALSE);
2036                 break;
2037         default:
2038                 g_return_if_reached ();
2039         }
2040
2041         /* Show */
2042         gtk_widget_show_all (priv->contents_widget);
2043 }
2044
2045 ModestMainWindowContentsStyle
2046 modest_main_window_get_contents_style (ModestMainWindow *self)
2047 {
2048         ModestMainWindowPrivate *priv;
2049
2050         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
2051
2052         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2053         return priv->contents_style;
2054 }
2055
2056
2057 static void 
2058 on_configuration_key_changed (ModestConf* conf, 
2059                               const gchar *key, 
2060                               ModestConfEvent event,
2061                               ModestConfNotificationId id, 
2062                               ModestMainWindow *self)
2063 {
2064         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2065         TnyAccount *account = NULL;
2066
2067         if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
2068                 return;
2069
2070         if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
2071                 return;
2072
2073         if (priv->folder_view) 
2074                 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
2075
2076         if (account && TNY_IS_ACCOUNT (account) &&
2077             strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID) == 0) {
2078                 GList *children;
2079                 GtkLabel *label;
2080                 const gchar *device_name;
2081                 gchar *new_text, *gray_color_markup;
2082                 
2083                 /* Get label */
2084                 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
2085                 label = GTK_LABEL (children->data);
2086                 
2087                 device_name = modest_conf_get_string (modest_runtime_get_conf(),
2088                                                       MODEST_CONF_DEVICE_NAME, NULL);
2089
2090                 gray_color_markup = get_gray_color_markup (GTK_WIDGET (self));          
2091                 new_text = create_device_name_visual_string (device_name, gray_color_markup);
2092                 
2093                 gtk_label_set_markup (label, new_text);
2094                 gtk_widget_show (GTK_WIDGET (label));
2095                 
2096                 g_free (gray_color_markup);
2097                 g_free (new_text);
2098                 g_list_free (children);
2099         }
2100         g_object_unref (account);
2101 }
2102
2103 static gboolean
2104 set_toolbar_transfer_mode (ModestMainWindow *self)
2105 {
2106         ModestMainWindowPrivate *priv = NULL;
2107         
2108         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2109
2110         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2111
2112         set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
2113         
2114         if (priv->progress_bar_timeout > 0) {
2115                 g_source_remove (priv->progress_bar_timeout);
2116                 priv->progress_bar_timeout = 0;
2117         }
2118
2119         return FALSE;
2120 }
2121
2122 static void 
2123 set_toolbar_mode (ModestMainWindow *self, 
2124                   ModestToolBarModes mode)
2125 {
2126         ModestWindowPrivate *parent_priv = NULL;
2127         ModestMainWindowPrivate *priv = NULL;
2128         GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
2129         
2130         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
2131
2132         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2133         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2134
2135         /* In case this was called before the toolbar exists: */
2136         if (!(parent_priv->toolbar))
2137                 return;
2138
2139         g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar)); 
2140         
2141         sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
2142         refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
2143         cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
2144
2145         /* Sets current toolbar mode */
2146         priv->current_toolbar_mode = mode;
2147
2148         /* Checks the dimming rules */
2149         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2150
2151         /* Show and hide toolbar items */
2152         switch (mode) {
2153         case TOOLBAR_MODE_NORMAL:
2154                 if (sort_action)
2155                         gtk_action_set_visible (sort_action, TRUE);
2156                 if (refresh_action)
2157                         gtk_action_set_visible (refresh_action, TRUE);
2158                 if (priv->progress_toolitem) {
2159                         gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
2160                         gtk_widget_hide (priv->progress_toolitem);
2161                 }
2162                 if (priv->progress_bar)
2163                         gtk_widget_hide (priv->progress_bar);
2164                 
2165                 if (cancel_action)
2166                         gtk_action_set_visible (cancel_action, FALSE);
2167
2168                 /* Hide toolbar if optimized view is enabled */
2169                 if (priv->optimized_view)
2170                         gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
2171                 break;
2172         case TOOLBAR_MODE_TRANSFER:
2173                 if (sort_action)
2174                         gtk_action_set_visible (sort_action, FALSE);
2175                 if (refresh_action)
2176                         gtk_action_set_visible (refresh_action, FALSE);
2177                 if (cancel_action)
2178                         gtk_action_set_visible (cancel_action, TRUE);
2179                 if (priv->progress_bar)
2180                         gtk_widget_show (priv->progress_bar);
2181                 if (priv->progress_toolitem) {
2182                         gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
2183                         gtk_widget_show (priv->progress_toolitem);
2184                 }
2185
2186                 /* Show toolbar if it's hiden (optimized view ) */
2187                 if (priv->optimized_view)
2188                         gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2189                 break;
2190         default:
2191                 g_return_if_reached ();
2192         }
2193 }
2194
2195 gboolean
2196 modest_main_window_transfer_mode_enabled (ModestMainWindow *self)
2197 {
2198         ModestMainWindowPrivate *priv;
2199
2200         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2201         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2202
2203         return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
2204 }
2205
2206 static void
2207 cancel_progressbar (GtkToolButton *toolbutton,
2208                     ModestMainWindow *self)
2209 {
2210         GSList *tmp;
2211         ModestMainWindowPrivate *priv;
2212         
2213         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2214
2215         /* Get operation observers and cancel all the operations */
2216         tmp = priv->progress_widgets;
2217         while (tmp) {
2218                 modest_progress_object_cancel_all_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2219                 tmp=g_slist_next(tmp);
2220         }
2221 }
2222
2223 static gboolean
2224 observers_empty (ModestMainWindow *self)
2225 {
2226         GSList *tmp = NULL;
2227         ModestMainWindowPrivate *priv;
2228         gboolean is_empty = TRUE;
2229         guint pending_ops = 0;
2230  
2231         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2232         tmp = priv->progress_widgets;
2233
2234         /* Check all observers */
2235         while (tmp && is_empty)  {
2236                 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2237                 is_empty = pending_ops == 0;
2238                 
2239                 tmp = g_slist_next(tmp);
2240         }
2241         
2242         return is_empty;
2243 }
2244
2245
2246 /**
2247  * Gets the toolbar mode needed for each mail operation. It stores in
2248  * @mode_changed if the toolbar mode has changed or not
2249  */
2250 static ModestToolBarModes
2251 get_toolbar_mode_from_mail_operation (ModestMainWindow *self,
2252                                       ModestMailOperation *mail_op,
2253                                       gboolean *mode_changed)
2254 {
2255         ModestToolBarModes mode;
2256         ModestMainWindowPrivate *priv;
2257
2258         *mode_changed = FALSE;
2259         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2260
2261         /* Get toolbar mode from operation id*/
2262         switch (modest_mail_operation_get_type_operation (mail_op)) {
2263         case MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE:
2264         case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
2265         case MODEST_MAIL_OPERATION_TYPE_OPEN:
2266                 mode = TOOLBAR_MODE_TRANSFER;
2267                 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
2268                         *mode_changed = TRUE;
2269                 break;
2270         default:
2271                 mode = TOOLBAR_MODE_NORMAL;             
2272         }
2273         return mode;
2274 }
2275
2276 static void 
2277 on_mail_operation_started (ModestMailOperation *mail_op,
2278                            gpointer user_data)
2279 {
2280         ModestMainWindow *self;
2281         ModestMailOperationTypeOperation op_type;
2282         ModestMainWindowPrivate *priv;
2283         ModestToolBarModes mode;
2284         GSList *tmp;
2285         gboolean mode_changed = FALSE;
2286         TnyAccount *account;
2287
2288         self = MODEST_MAIN_WINDOW (user_data);
2289         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2290
2291         /* Do not show progress for receiving operations if the
2292            account is the local account or the MMC one */
2293         op_type = modest_mail_operation_get_type_operation (mail_op);
2294         account = modest_mail_operation_get_account (mail_op);
2295         if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2296                 gboolean is_remote;
2297
2298                 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2299                               modest_tny_account_is_memory_card_account (account));
2300                 if (!is_remote) {
2301                         g_object_unref (account);
2302                         return;
2303                 }
2304
2305                 /* Show information banner. Remove old timeout */
2306                 if (priv->retrieving_banner_timeout > 0) {
2307                         g_source_remove (priv->retrieving_banner_timeout);
2308                         priv->retrieving_banner_timeout = 0;
2309                 }
2310                 /* Create a new timeout */
2311                 priv->retrieving_banner_timeout = 
2312                         g_timeout_add (2000, show_retrieving_banner, self);
2313         }
2314         g_object_unref (account);
2315                
2316         /* Get toolbar mode from operation id*/
2317         mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2318
2319         /* Add operation observers and change toolbar if neccessary*/
2320         tmp = priv->progress_widgets;
2321         if (mode == TOOLBAR_MODE_TRANSFER) {
2322                 if (mode_changed) {
2323                         GObject *source = modest_mail_operation_get_source(mail_op);
2324                         if (G_OBJECT (self) == source) {
2325                                 set_toolbar_transfer_mode(self);
2326                         }
2327                         g_object_unref (source);
2328                 }
2329
2330                 while (tmp) {
2331                         modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2332                                                               mail_op);
2333                         tmp = g_slist_next (tmp);
2334                 }
2335         }
2336
2337         /* Update the main menu as well, we need to explicitely do
2338            this in order to enable/disable accelerators */
2339         modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
2340 }
2341
2342 static void 
2343 on_mail_operation_finished (ModestMailOperation *mail_op,
2344                             gpointer user_data)
2345 {
2346         ModestToolBarModes mode;
2347         ModestMailOperationTypeOperation op_type;
2348         GSList *tmp = NULL;
2349         ModestMainWindow *self;
2350         gboolean mode_changed;
2351         TnyAccount *account;
2352         ModestMainWindowPrivate *priv;
2353
2354         self = MODEST_MAIN_WINDOW (user_data);
2355         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2356
2357         /* The mail operation was not added to the progress objects if
2358            the account was the local account or the MMC one */
2359         op_type = modest_mail_operation_get_type_operation (mail_op);
2360         account = modest_mail_operation_get_account (mail_op);
2361         if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2362                 gboolean is_remote;
2363
2364                 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2365                               modest_tny_account_is_memory_card_account (account));
2366                 if (!is_remote) {
2367                         g_object_unref (account);
2368                         return;
2369                 }
2370
2371                 /* Remove old timeout */
2372                 if (priv->retrieving_banner_timeout > 0) {
2373                         g_source_remove (priv->retrieving_banner_timeout);
2374                         priv->retrieving_banner_timeout = 0;
2375                 }
2376
2377                 /* Remove the banner if exists */
2378                 if (priv->retrieving_banner) {
2379                         gtk_widget_destroy (priv->retrieving_banner);
2380                         priv->retrieving_banner = NULL;
2381                 }
2382         }
2383         g_object_unref (account);
2384
2385         /* Get toolbar mode from operation id*/
2386         mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2387
2388         /* Change toolbar mode */
2389         tmp = priv->progress_widgets;
2390         if (mode == TOOLBAR_MODE_TRANSFER) {                    
2391                 while (tmp) {
2392                         modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2393                                                                  mail_op);
2394                         tmp = g_slist_next (tmp);
2395                 }
2396                 
2397                 /* If no more operations are being observed, NORMAL mode is enabled again */
2398                 if (observers_empty (self)) {
2399                         set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);                           
2400                 }
2401         }
2402 }
2403
2404 static void
2405 on_queue_changed (ModestMailOperationQueue *queue,
2406                   ModestMailOperation *mail_op,
2407                   ModestMailOperationQueueNotification type,
2408                   ModestMainWindow *self)
2409 {
2410         ModestMainWindowPrivate *priv;
2411
2412         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2413
2414         if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
2415                 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2416                                                                G_OBJECT (mail_op),
2417                                                                "operation-started",
2418                                                                G_CALLBACK (on_mail_operation_started),
2419                                                                self);
2420                 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2421                                                                G_OBJECT (mail_op),
2422                                                                "operation-finished",
2423                                                                G_CALLBACK (on_mail_operation_finished),
2424                                                                self);
2425         } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
2426                 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2427                                                                   G_OBJECT (mail_op),
2428                                                                   "operation-started");
2429                 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2430                                                                   G_OBJECT (mail_op),
2431                                                                   "operation-finished");
2432         }
2433 }
2434
2435 static void
2436 set_account_visible(ModestMainWindow *self, const gchar *acc_name)
2437 {
2438         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2439         GtkAction *action;
2440         ModestAccountMgr *mgr;
2441         ModestAccountSettings *settings;
2442         ModestServerAccountSettings *store_settings = NULL;
2443
2444         /* Get account data */
2445         mgr = modest_runtime_get_account_mgr ();
2446         settings = modest_account_mgr_load_account_settings (mgr, acc_name);
2447         if (settings)
2448                 store_settings = modest_account_settings_get_store_settings (settings);
2449
2450         /* Set the new visible & active account */
2451         if (settings && (modest_server_account_settings_get_account_name (store_settings)!= NULL)) { 
2452                 const gchar *account_name;
2453
2454                 account_name = modest_account_settings_get_account_name (settings);
2455
2456                 modest_folder_view_set_account_id_of_visible_server_account 
2457                         (priv->folder_view,
2458                          modest_server_account_settings_get_account_name (store_settings));
2459                 modest_window_set_active_account (MODEST_WINDOW (self), account_name);
2460                 action = gtk_action_group_get_action (priv->view_additions_group, account_name);
2461                 if (action != NULL) {
2462                         if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
2463                                 modest_utils_toggle_action_set_active_block_notify (
2464                                         GTK_TOGGLE_ACTION (action),
2465                                         TRUE);
2466                         }
2467                 }
2468         }
2469         
2470         modest_folder_view_select_first_inbox_or_local (priv->folder_view);
2471
2472
2473         /* Free */
2474         if (settings) {
2475                 g_object_unref (store_settings);
2476                 g_object_unref (settings);
2477         }
2478 }
2479
2480 /* Make sure that at least one account is "viewed": */
2481 static void
2482 set_at_least_one_account_visible(ModestMainWindow *self)
2483 {
2484         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2485         ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2486
2487         if (!(priv->folder_view)) {
2488                 /* It is too early to do this. */
2489                 return; 
2490         }
2491         
2492         const gchar *active_server_account_name = 
2493                 modest_folder_view_get_account_id_of_visible_server_account (priv->folder_view);
2494         
2495         if (!active_server_account_name ||
2496                 !modest_account_mgr_account_exists (account_mgr, active_server_account_name, TRUE))
2497         {
2498                 gchar* first_modest_name = modest_account_mgr_get_first_account_name (account_mgr);
2499                 gchar* default_modest_name = modest_account_mgr_get_default_account (account_mgr);
2500                 if (default_modest_name) {
2501                         set_account_visible (self, default_modest_name);
2502                 } else if (first_modest_name) {
2503                         set_account_visible (self, first_modest_name);
2504                 }
2505                 g_free (first_modest_name);
2506                 g_free (default_modest_name);
2507         }
2508 }
2509
2510 static void 
2511 on_show_account_action_toggled  (GtkToggleAction *action,
2512                                    gpointer user_data)
2513 {
2514         ModestMainWindow *self = MODEST_MAIN_WINDOW (user_data);
2515
2516         const gchar *acc_name = gtk_action_get_name (GTK_ACTION (action));
2517         if (gtk_toggle_action_get_active (action))
2518                 set_account_visible (self, acc_name);
2519 }
2520
2521 static void
2522 refresh_account (const gchar *account_name)
2523 {
2524         ModestWindow *win;
2525         
2526         /* win must already exists here, obviously */ 
2527         win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
2528                                                  FALSE);
2529         if (!win) {
2530                 g_warning ("%s: BUG: no main window!", __FUNCTION__);
2531                 return;
2532         }
2533         
2534         /* If account_name == NULL, we must update all (option All) */
2535         if (!account_name)
2536                 modest_ui_actions_do_send_receive_all (win, TRUE);
2537         else
2538                 modest_ui_actions_do_send_receive (account_name, TRUE, win);
2539         
2540 }
2541
2542 static void 
2543 on_refresh_account_action_activated  (GtkAction *action,
2544                                       gpointer user_data)
2545 {
2546         refresh_account ((const gchar*) user_data);
2547 }
2548
2549 static void
2550 on_send_receive_csm_activated (GtkMenuItem *item,
2551                                gpointer user_data)
2552 {
2553         refresh_account ((const gchar*) user_data);
2554 }
2555
2556 static gboolean
2557 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2558 {
2559         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2560
2561         hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2562         return FALSE;
2563
2564 }
2565
2566 static gboolean
2567 on_folder_view_focus_in (GtkWidget *widget, GdkEventFocus *event, gpointer userdata)
2568 {
2569         ModestMainWindow *main_window = NULL;
2570         
2571         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2572         main_window = MODEST_MAIN_WINDOW (userdata);
2573         
2574         /* Update toolbar dimming state */
2575         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2576
2577         return FALSE;
2578 }
2579
2580 static gboolean
2581 on_header_view_focus_in (GtkWidget *widget,
2582                          GdkEventFocus *event,
2583                          gpointer userdata)
2584 {
2585         ModestMainWindow *main_window = NULL;
2586
2587         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2588
2589         main_window = MODEST_MAIN_WINDOW (userdata);
2590
2591         /* Update toolbar dimming state */
2592         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2593
2594         return FALSE;
2595 }
2596
2597 static void 
2598 on_folder_selection_changed (ModestFolderView *folder_view,
2599                              TnyFolderStore *folder_store, 
2600                              gboolean selected,
2601                              ModestMainWindow *main_window)
2602 {
2603         ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (main_window);
2604         GtkAction *action = NULL;
2605         gboolean show_reply = TRUE;
2606         gboolean show_forward = TRUE;
2607         gboolean show_cancel_send = FALSE;
2608         gboolean show_clipboard = TRUE;
2609         gboolean show_delete = TRUE;
2610
2611         if (selected) {
2612                 if (TNY_IS_ACCOUNT (folder_store)) {
2613                         show_reply = show_forward = show_cancel_send = show_clipboard = show_delete = FALSE;
2614                 } else if (TNY_IS_FOLDER (folder_store)) {
2615                         if (modest_tny_folder_is_local_folder (TNY_FOLDER (folder_store))) {
2616                                 TnyFolderType folder_type = modest_tny_folder_get_local_or_mmc_folder_type (
2617                                         TNY_FOLDER (folder_store));
2618                                 switch (folder_type) {
2619                                 case TNY_FOLDER_TYPE_DRAFTS:
2620                                         show_clipboard = show_delete = TRUE;
2621                                         show_reply = show_forward = show_cancel_send = FALSE;
2622                                         break;
2623                                 case TNY_FOLDER_TYPE_SENT:
2624                                         show_forward = show_clipboard = show_delete = TRUE;
2625                                         show_reply = show_cancel_send = FALSE;
2626                                         break;
2627                                 case TNY_FOLDER_TYPE_OUTBOX:
2628                                         show_clipboard = show_delete = show_cancel_send = TRUE;
2629                                         show_reply = show_forward = FALSE;
2630                                         break;
2631                                 case TNY_FOLDER_TYPE_INVALID:
2632                                         g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
2633                                         break;
2634                                 default:
2635                                         show_reply = show_forward = show_clipboard = show_delete = TRUE;
2636                                         show_cancel_send = FALSE;
2637                                 }
2638                         } else {
2639                                 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2640                                 show_cancel_send = FALSE;
2641                         }
2642                 }
2643         }
2644
2645         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReply");
2646         gtk_action_set_visible (action, show_reply);
2647         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReplyAll");
2648         gtk_action_set_visible (action, show_reply);
2649         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMForward");
2650         gtk_action_set_visible (action, show_forward);
2651         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCancelSending");
2652         gtk_action_set_visible (action, show_cancel_send);
2653         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMDelete");
2654         gtk_action_set_visible (action, show_delete);
2655
2656         /* We finally call to the ui actions handler, after updating properly
2657          * the header view CSM */
2658         modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window);
2659 }
2660
2661 gboolean 
2662 modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window,
2663                                                    GtkTreeModel *model,
2664                                                    GtkTreeRowReference *row_reference,
2665                                                    ModestMainWindow *self)
2666 {
2667         ModestMainWindowPrivate *priv = NULL;
2668         GtkTreeModel *header_model = NULL;
2669         GtkTreePath *path = NULL;
2670
2671         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (view_window), FALSE);
2672         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2673         g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE);
2674
2675         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2676         header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->header_view));
2677
2678         /* Do nothing if we changed the folder in the main view */
2679         if (header_model != model)
2680                 return FALSE;
2681
2682         /* Select the message in the header view */
2683         path = gtk_tree_row_reference_get_path (row_reference);
2684         gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->header_view),
2685                                   path, NULL, FALSE);
2686         gtk_tree_path_free (path);
2687
2688         return TRUE;
2689 }
2690
2691 static gboolean
2692 show_updating_banner (gpointer user_data)
2693 {
2694         ModestMainWindowPrivate *priv = NULL;
2695
2696         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2697
2698         if (priv->updating_banner == NULL) {
2699
2700                 /* We're outside the main lock */
2701                 gdk_threads_enter ();
2702                 priv->updating_banner = 
2703                         modest_platform_animation_banner (GTK_WIDGET (user_data), NULL,
2704                                                           _CS ("ckdg_pb_updating"));
2705                 gdk_threads_leave ();
2706         }
2707
2708         /* Remove timeout */
2709         priv->updating_banner_timeout = 0;
2710         return FALSE;
2711 }
2712
2713 /**
2714  * We use this function to show/hide a progress banner showing
2715  * "Updating" while the header view is being filled. We're not showing
2716  * it unless the update takes more than 2 seconds
2717  *
2718  * If starting = TRUE then the refresh is starting, otherwise it means
2719  * that is has just finished
2720  */
2721 static void 
2722 on_updating_msg_list (ModestHeaderView *header_view,
2723                       gboolean starting,
2724                       gpointer user_data)
2725 {
2726         ModestMainWindowPrivate *priv = NULL;
2727
2728         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2729         
2730         /* Remove old timeout */
2731         if (priv->updating_banner_timeout > 0) {
2732                 g_source_remove (priv->updating_banner_timeout);
2733                 priv->updating_banner_timeout = 0;
2734         }
2735
2736         /* Create a new timeout */
2737         if (starting) {
2738                 priv->updating_banner_timeout = 
2739                         g_timeout_add (2000, show_updating_banner, user_data);
2740         } else {
2741                 /* Remove the banner if exists */
2742                 if (priv->updating_banner) {
2743                         gtk_widget_destroy (priv->updating_banner);
2744                         priv->updating_banner = NULL;
2745                 }
2746         }
2747 }
2748
2749 gboolean
2750 modest_main_window_screen_is_on (ModestMainWindow *self)
2751 {
2752         ModestMainWindowPrivate *priv = NULL;
2753
2754         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(self), FALSE);
2755
2756         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2757         
2758         return (priv->display_state == OSSO_DISPLAY_ON) ? TRUE : FALSE;
2759 }
2760
2761 static gboolean
2762 show_retrieving_banner (gpointer user_data)
2763 {
2764         ModestMainWindowPrivate *priv = NULL;
2765
2766         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2767
2768         if (priv->retrieving_banner == NULL) {
2769
2770                 /* We're outside the main lock */
2771                 gdk_threads_enter ();
2772                 priv->retrieving_banner = 
2773                         modest_platform_animation_banner (GTK_WIDGET (user_data), NULL,
2774                                                           _("mcen_ib_getting_items"));
2775                 gdk_threads_leave ();
2776         }
2777
2778         /* Remove timeout */
2779         priv->retrieving_banner_timeout = 0;
2780         return FALSE;
2781 }