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