* Fixes NB#66958, now menus show the account names ellipsized
[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                                         gchar *escaped = g_markup_printf_escaped ("<b>%s</b>", display_name);
709                                         gtk_label_set_markup (GTK_LABEL (label), escaped);
710                                         g_free (escaped);
711                                 } else {
712                                         gtk_label_set_text (GTK_LABEL (label), display_name);
713                                 }
714
715                                 item = gtk_menu_item_new ();
716                                 gtk_container_add (GTK_CONTAINER (item), label);
717
718                                 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
719                                 g_signal_connect_data (G_OBJECT (item), 
720                                                        "activate", 
721                                                        G_CALLBACK (on_send_receive_csm_activated),
722                                                        g_strdup (account_name),
723                                                        (GClosureNotify) g_free,
724                                                        0);
725                         }
726                         g_free (item_name);
727                 }
728
729                 /* Frees */
730                 g_free (display_name);
731         }
732
733         gtk_ui_manager_insert_action_group (parent_priv->ui_manager, priv->view_additions_group, 1);
734
735         /* We cannot do this in the loop above because this relies on the action
736          * group being inserted. This makes the default account appear in bold.
737          * I agree it is a rather ugly way, but I don't see another possibility. armin. */
738         for (i = 0; i < num_accounts; i++) {
739                 gchar *item_name, *path;
740                 GtkWidget *item;
741                 ModestAccountSettings *settings;
742                 const gchar *account_name;
743                 gboolean is_default;
744
745                 settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
746                 account_name = modest_account_settings_get_account_name (settings);
747                 is_default = (account_name && default_account && !strcmp (account_name, default_account));
748
749                 /* Get the item of the view menu */
750                 item_name = g_strconcat (account_name, "Menu", NULL);
751                 path = g_strconcat ("/MenuBar/ViewMenu/ViewMenuAdditions/", item_name, NULL);
752                 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                                 if (is_default) {
760                                         gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
761                                         gtk_label_set_markup (GTK_LABEL (child), bold_name);
762                                         g_free (bold_name);
763                                 }
764                                 gtk_label_set_ellipsize (GTK_LABEL (child),  PANGO_ELLIPSIZE_END);
765                         }
766                 }
767                         
768                 /* Get the item of the tools menu */
769                 path = g_strconcat("/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions/", item_name, NULL);
770                 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
771                 g_free (path);
772
773                 if (item) {
774                         GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
775                         if (GTK_IS_LABEL (child)) {
776                                 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
777                                 if (is_default) {
778                                         gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
779                                         gtk_label_set_markup (GTK_LABEL (child), bold_name);
780                                         g_free (bold_name);
781                                 }
782                                 gtk_label_set_ellipsize (GTK_LABEL (child),  PANGO_ELLIPSIZE_END);
783                         }
784                 }
785
786                 g_free(item_name);
787                 g_object_unref (settings);
788         }
789
790         if (num_accounts > 1) {
791                 /* Disconnect the tap-and-hold-query if it's connected */
792                 if (modest_signal_mgr_is_connected (priv->sighandlers, 
793                                                     G_OBJECT (send_receive_button),
794                                                     "tap-and-hold-query"))
795                         priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers, 
796                                                                           G_OBJECT (send_receive_button),
797                                                                           "tap-and-hold-query");
798
799                 /* Mandatory in order to view the menu contents */
800                 gtk_widget_show_all (priv->accounts_popup);
801
802                 /* Setup tap_and_hold just if was not done before*/
803                 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
804                         gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
805         } else {
806                 /* Connect the tap-and-hold-query in order not to show the CSM */
807                 if (!modest_signal_mgr_is_connected (priv->sighandlers, 
808                                                      G_OBJECT (send_receive_button),
809                                                      "tap-and-hold-query"))
810                         priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, 
811                                                                        G_OBJECT (send_receive_button),
812                                                                        "tap-and-hold-query",
813                                                                        G_CALLBACK (tap_and_hold_query_cb), 
814                                                                        NULL);
815         }
816
817         /* Frees */
818         g_slist_free (accounts);
819         g_free (default_account);
820
821
822         /* Make sure that at least one account is viewed if there are any 
823          * accounts, for instance when adding the first account: */
824         set_at_least_one_account_visible (self);
825 }
826
827 static void
828 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
829 {
830         if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
831                 gtk_scrolled_window_add_with_viewport
832                         (GTK_SCROLLED_WINDOW(win), widget);
833         else
834                 gtk_container_add (GTK_CONTAINER(win),
835                                    widget);
836 }
837
838
839 typedef struct {
840         TnySendQueue *queue;
841         guint signal;
842 } QueueErrorSignal;
843
844 static void
845 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
846 {
847         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
848
849         GList *oerrsignals = priv->queue_err_signals;
850         while (oerrsignals) {
851                 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
852                 g_signal_handler_disconnect (esignal->queue, esignal->signal);
853                 g_slice_free (QueueErrorSignal, esignal);
854                 oerrsignals = g_list_next (oerrsignals);
855         }
856         g_list_free (priv->queue_err_signals);
857         priv->queue_err_signals = NULL;
858 }
859
860
861 static void
862 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
863 {
864         g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
865
866         /* Update dimmed */
867         modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
868 }
869
870 static void
871 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
872 {
873         g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
874
875         /* Update visibility */
876
877         /* Update dimmed */
878         modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
879 }
880
881 static void
882 modest_main_window_disconnect_signals (ModestWindow *self)
883 {       
884         ModestMainWindowPrivate *priv;  
885         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
886
887         modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
888         priv->sighandlers = NULL;       
889 }
890
891 static void
892 connect_signals (ModestMainWindow *self)
893 {       
894         ModestWindowPrivate *parent_priv;
895         ModestMainWindowPrivate *priv;
896         GtkWidget *menu;
897         
898         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
899         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
900
901         /* folder view */
902         
903         priv->sighandlers = 
904                 modest_signal_mgr_connect (priv->sighandlers,
905                                            G_OBJECT(priv->folder_view), "key-press-event",
906                                            G_CALLBACK(on_inner_widgets_key_pressed), self);
907         priv->sighandlers = 
908                 modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), 
909                                            "folder_selection_changed",
910                                            G_CALLBACK (on_folder_selection_changed), 
911                                            self);
912         priv->sighandlers = 
913                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view), 
914                                            "folder-display-name-changed",
915                                            G_CALLBACK (modest_ui_actions_on_folder_display_name_changed), 
916                                            self);
917         priv->sighandlers = 
918                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->folder_view), 
919                                            "focus-in-event", 
920                                            G_CALLBACK (on_folder_view_focus_in), 
921                                            self);
922
923         /* Folder view CSM */
924         menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
925         gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
926         priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), "tap-and-hold",
927                                                        G_CALLBACK(_folder_view_csm_menu_activated),
928                                                        self);
929         /* header view */
930         priv->sighandlers = 
931                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_selected",
932                                            G_CALLBACK(modest_ui_actions_on_header_selected), self);
933         priv->sighandlers = 
934                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_activated",
935                                            G_CALLBACK(modest_ui_actions_on_header_activated), self);
936         priv->sighandlers = 
937                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "item_not_found",
938                                            G_CALLBACK(modest_ui_actions_on_item_not_found), self);
939         priv->sighandlers = 
940                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "key-press-event",
941                                            G_CALLBACK(on_inner_widgets_key_pressed), self);
942         priv->sighandlers = 
943                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "msg_count_changed",
944                                            G_CALLBACK(on_msg_count_changed), self);
945         priv->sighandlers = 
946                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->header_view), "focus-in-event",
947                                            G_CALLBACK (on_header_view_focus_in), self);
948         priv->sighandlers = 
949                 modest_signal_mgr_connect (priv->sighandlers,
950                                            G_OBJECT (priv->header_view), 
951                                            "updating-msg-list",
952                                            G_CALLBACK (on_updating_msg_list), 
953                                            self);
954         
955         /* Header view CSM */
956         menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
957         gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
958         priv->sighandlers = 
959                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "tap-and-hold",
960                                            G_CALLBACK(_header_view_csm_menu_activated),
961                                            self);
962         
963         /* window */
964         priv->sighandlers = 
965                 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (self), "window-state-event",
966                                            G_CALLBACK (modest_main_window_window_state_event),
967                                            NULL);
968
969         /* Mail Operation Queue */
970         priv->sighandlers = 
971                 modest_signal_mgr_connect (priv->sighandlers,
972                                            G_OBJECT (modest_runtime_get_mail_operation_queue ()),
973                                            "queue-changed", 
974                                            G_CALLBACK (on_queue_changed), self);
975         
976         /* Track changes in the device name */
977         priv->sighandlers = 
978                 modest_signal_mgr_connect (priv->sighandlers,
979                                            G_OBJECT(modest_runtime_get_conf ()),
980                                            "key_changed", 
981                                            G_CALLBACK (on_configuration_key_changed), 
982                                            self);
983         
984         /* Track account changes. We need to refresh the toolbar */
985         priv->sighandlers = 
986                 modest_signal_mgr_connect (priv->sighandlers,
987                                            G_OBJECT (modest_runtime_get_account_store ()),
988                                            "account_inserted", 
989                                            G_CALLBACK (on_account_inserted),
990                                            self);
991         priv->sighandlers = 
992                 modest_signal_mgr_connect (priv->sighandlers,
993                                            G_OBJECT (modest_runtime_get_account_store ()),
994                                            "account_removed", 
995                                            G_CALLBACK (on_account_removed),
996                                            self);
997
998         /* We need to refresh the send & receive menu to change the bold
999          * account when the default account changes. */
1000         priv->sighandlers = 
1001                 modest_signal_mgr_connect (priv->sighandlers,
1002                                            G_OBJECT (modest_runtime_get_account_mgr ()),
1003                                            "default_account_changed", 
1004                                            G_CALLBACK (on_default_account_changed),
1005                                            self);
1006
1007         /* Account store */
1008         priv->sighandlers = 
1009                 modest_signal_mgr_connect (priv->sighandlers,
1010                                            G_OBJECT (modest_runtime_get_account_store ()),
1011                                            "account_changed", 
1012                                            G_CALLBACK (on_account_changed),
1013                                            self);
1014
1015         priv->sighandlers = 
1016                 modest_signal_mgr_connect (priv->sighandlers,
1017                                            G_OBJECT (modest_runtime_get_account_store()), 
1018                                            "password_requested",
1019                                            G_CALLBACK (modest_ui_actions_on_password_requested), 
1020                                            self);
1021 }
1022
1023 static void 
1024 on_hildon_program_is_topmost_notify(GObject *self,
1025                                     GParamSpec *propert_param, 
1026                                     gpointer user_data)
1027 {
1028         HildonProgram *app = HILDON_PROGRAM (self);
1029         
1030         /* Note that use of hildon_program_set_can_hibernate() 
1031          * is generally referred to as "setting the killable flag", 
1032          * though hibernation does not seem equal to death.
1033          * murrayc */
1034                  
1035         if (hildon_program_get_is_topmost (app)) {
1036                 /* Prevent hibernation when the progam comes to the foreground,
1037                  * because hibernation should only happen when the application 
1038                  * is in the background: */
1039                 hildon_program_set_can_hibernate (app, FALSE);
1040
1041                 /* Remove new mail visual notifications */
1042                 modest_platform_remove_new_mail_notifications (TRUE);
1043         } else {
1044                 /* Allow hibernation if the program has gone to the background: */
1045                 
1046                 /* However, prevent hibernation while the settings are being changed: */
1047                 const gboolean hibernation_prevented = 
1048                         modest_window_mgr_get_hibernation_is_prevented (
1049                                                                         modest_runtime_get_window_mgr ()); 
1050         
1051                 if (hibernation_prevented)
1052                         hildon_program_set_can_hibernate (app, FALSE);
1053                 else {
1054                         /* Allow hibernation, after saving the state: */
1055                         modest_osso_save_state();
1056                         hildon_program_set_can_hibernate (app, TRUE);
1057                 }
1058         }       
1059 }
1060
1061 static void
1062 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
1063 {
1064         GtkWidget *folder_win = (GtkWidget *) user_data;
1065         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1066         
1067         priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
1068         wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
1069
1070         gtk_widget_show (GTK_WIDGET (priv->folder_view));
1071
1072         /* Connect signals */
1073         connect_signals (MODEST_MAIN_WINDOW (self));
1074
1075         /* Set account store */
1076         tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
1077                                                   TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1078
1079         /* Load previous osso state, for instance if we are being restored from 
1080          * hibernation:  */
1081         modest_osso_load_state ();
1082
1083         /* Restore window & widget settings */  
1084         restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
1085
1086         /* Check if accounts exist and show the account wizard if not */
1087         gboolean accounts_exist = 
1088                 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1089
1090         if (!accounts_exist) {
1091                 /* This is necessary to have the main window shown behind the dialog 
1092                 It's an ugly hack... jschmid */
1093                 gtk_widget_show_all(GTK_WIDGET(self));
1094                 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
1095         } else {
1096                 GSList *accounts;
1097                 GtkAction *send_receive_all;
1098                 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1099                 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
1100                 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager, 
1101                                                               "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1102                 gtk_action_set_visible (send_receive_all, g_slist_length (accounts) > 0);
1103                 modest_account_mgr_free_account_names (accounts);
1104                 update_menus (MODEST_MAIN_WINDOW (self));
1105         }
1106 }
1107
1108 static void 
1109 osso_display_event_cb (osso_display_state_t state, 
1110                        gpointer data)
1111 {
1112         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (data);
1113
1114         priv->display_state = state;
1115
1116         /* Stop blinking if the screen becomes on */
1117         if (priv->display_state == OSSO_DISPLAY_ON)
1118                 modest_platform_remove_new_mail_notifications (TRUE);
1119 }
1120
1121 ModestWindow *
1122 modest_main_window_new (void)
1123 {
1124         ModestMainWindow *self = NULL;  
1125         ModestMainWindowPrivate *priv = NULL;
1126         ModestWindowPrivate *parent_priv = NULL;
1127         GtkWidget *folder_win = NULL;
1128         ModestDimmingRulesGroup *menu_rules_group = NULL;
1129         ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1130         GtkActionGroup *action_group = NULL;
1131         GError *error = NULL;
1132         HildonProgram *app;
1133         ModestConf *conf = NULL;
1134         GtkAction *action = NULL;
1135         GdkPixbuf *window_icon;
1136         
1137         self  = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
1138         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1139         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1140
1141         parent_priv->ui_manager = gtk_ui_manager_new();
1142         parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
1143
1144         action_group = gtk_action_group_new ("ModestMainWindowActions");
1145         gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
1146
1147         menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1148         toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1149
1150         /* Add common actions */
1151         gtk_action_group_add_actions (action_group,
1152                                       modest_action_entries,
1153                                       G_N_ELEMENTS (modest_action_entries),
1154                                       self);
1155
1156         gtk_action_group_add_actions (action_group,
1157                                       modest_folder_view_action_entries,
1158                                       G_N_ELEMENTS (modest_folder_view_action_entries),
1159                                       self);
1160
1161         gtk_action_group_add_actions (action_group,
1162                                       modest_header_view_action_entries,
1163                                       G_N_ELEMENTS (modest_header_view_action_entries),
1164                                       self);
1165
1166         gtk_action_group_add_toggle_actions (action_group,
1167                                              modest_toggle_action_entries,
1168                                              G_N_ELEMENTS (modest_toggle_action_entries),
1169                                              self);
1170
1171         gtk_action_group_add_toggle_actions (action_group,
1172                                              modest_main_window_toggle_action_entries,
1173                                              G_N_ELEMENTS (modest_main_window_toggle_action_entries),
1174                                              self);
1175
1176         gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
1177         g_object_unref (action_group);
1178
1179         /* Load the UI definition */
1180         gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
1181                                          MODEST_UIDIR "modest-main-window-ui.xml", &error);
1182         if (error != NULL) {
1183                 g_warning ("Could not merge modest-ui.xml: %s", error->message);
1184                 g_error_free (error);
1185                 error = NULL;
1186         }
1187
1188         /* Add common dimming rules */
1189         modest_dimming_rules_group_add_rules (menu_rules_group, 
1190                                               modest_main_window_menu_dimming_entries,
1191                                               G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
1192                                               MODEST_WINDOW (self));
1193         modest_dimming_rules_group_add_rules (toolbar_rules_group, 
1194                                               modest_main_window_toolbar_dimming_entries,
1195                                               G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
1196                                               MODEST_WINDOW (self));
1197
1198         /* Insert dimming rules group for this window */
1199         modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1200         modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1201         g_object_unref (menu_rules_group);
1202         g_object_unref (toolbar_rules_group);
1203         
1204         /* Add accelerators */
1205         gtk_window_add_accel_group (GTK_WINDOW (self), 
1206                                     gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
1207
1208         /* Menubar. Update the state of some toggles */
1209         parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1210         conf = modest_runtime_get_conf ();
1211         action = gtk_ui_manager_get_action (parent_priv->ui_manager, 
1212                                             "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
1213         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1214                                       modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR, NULL));
1215         action = gtk_ui_manager_get_action (parent_priv->ui_manager, 
1216                                             "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
1217         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1218                                       modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
1219         hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
1220         gtk_widget_show (parent_priv->menubar);
1221
1222         /* Get device name */
1223         modest_maemo_utils_get_device_name ();
1224
1225         /* header view */
1226         priv->header_view =
1227                 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
1228         if (!priv->header_view)
1229                 g_printerr ("modest: cannot instantiate header view\n");
1230         modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
1231         modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
1232                                       MODEST_CONF_HEADER_VIEW_KEY);
1233
1234         /* Other style properties of header view */
1235         g_object_set (G_OBJECT (priv->header_view), 
1236                       "rules-hint", FALSE,
1237                       NULL);
1238         /* gtk_widget_show (priv->header_view); */
1239
1240         /* Empty view */ 
1241         priv->empty_view = create_empty_view ();
1242         gtk_widget_show (priv->empty_view);
1243                  
1244         /* Create scrolled windows */
1245         folder_win = gtk_scrolled_window_new (NULL, NULL);
1246         priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
1247         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
1248                                         GTK_POLICY_NEVER,
1249                                         GTK_POLICY_AUTOMATIC);
1250         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
1251                                         GTK_POLICY_NEVER,
1252                                         GTK_POLICY_AUTOMATIC);
1253         /* gtk_widget_show (priv->contents_widget); */
1254
1255         /* paned */
1256         priv->main_paned = gtk_hpaned_new ();
1257         gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
1258         gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
1259         gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
1260
1261         /* putting it all together... */
1262         priv->main_vbox = gtk_vbox_new (FALSE, 6);
1263         gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
1264         gtk_widget_show (priv->main_vbox);
1265         
1266         gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
1267         
1268         app = hildon_program_get_instance ();
1269         hildon_program_add_window (app, HILDON_WINDOW (self));
1270         
1271         g_signal_connect (G_OBJECT(app), "notify::is-topmost",
1272                 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
1273
1274         g_signal_connect (G_OBJECT(self), "show",
1275                           G_CALLBACK (modest_main_window_on_show), folder_win);
1276                 
1277         /* Set window icon */
1278         window_icon = modest_platform_get_icon (MODEST_APP_ICON, MODEST_ICON_SIZE_BIG);
1279         if (window_icon) {
1280                 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
1281                 g_object_unref (window_icon);
1282         }
1283
1284         /* Listen for changes in the screen, we don't want to show a
1285            led pattern when the display is on for example */
1286         osso_hw_set_display_event_cb (modest_maemo_utils_get_osso_context (),
1287                                       osso_display_event_cb,
1288                                       self); 
1289
1290         /* Dont't restore settings here, 
1291          * because it requires a gtk_widget_show(), 
1292          * and we don't want to do that until later,
1293          * so that the UI is not visible for non-menu D-Bus activation.
1294          */
1295
1296         return MODEST_WINDOW(self);
1297 }
1298
1299 void 
1300 modest_main_window_set_style (ModestMainWindow *self, 
1301                               ModestMainWindowStyle style)
1302 {
1303         ModestMainWindowPrivate *priv;
1304         ModestWindowPrivate *parent_priv;
1305         GtkAction *action;
1306         gboolean active;
1307
1308         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1309
1310         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1311         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1312
1313         /* no change -> nothing to do */
1314         if (priv->style == style)
1315                 return;
1316
1317        /* Get toggle button and update the state if needed. This will
1318           happen only when the set_style is not invoked from the UI,
1319           for example when it's called from widget memory */
1320        action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1321        active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
1322        if ((active && style == MODEST_MAIN_WINDOW_STYLE_SIMPLE) ||
1323            (!active && style == MODEST_MAIN_WINDOW_STYLE_SPLIT)) {
1324                g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1325                gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), !active);
1326                g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1327        }
1328
1329         priv->style = style;
1330         switch (style) {
1331         case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
1332                 /* Remove main paned */
1333                 g_object_ref (priv->main_paned);
1334                 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1335
1336                 /* Reparent the contents widget to the main vbox */
1337                 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
1338
1339                 break;
1340         case MODEST_MAIN_WINDOW_STYLE_SPLIT:
1341                 /* Remove header view */
1342                 g_object_ref (priv->contents_widget);
1343                 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
1344
1345                 /* Reparent the main paned */
1346                 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
1347                 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1348
1349                 break;
1350         default:
1351                 g_return_if_reached ();
1352         }
1353
1354         /* Let header view grab the focus if it's being shown */
1355         if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1356                 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1357         else 
1358                 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1359
1360         /* Show changes */
1361         gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1362 }
1363
1364 ModestMainWindowStyle
1365 modest_main_window_get_style (ModestMainWindow *self)
1366 {
1367         ModestMainWindowPrivate *priv;
1368
1369         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1370
1371         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1372         return priv->style;
1373 }
1374
1375 static void
1376 toolbar_resize (ModestMainWindow *self)
1377 {
1378         ModestMainWindowPrivate *priv = NULL;
1379         ModestWindowPrivate *parent_priv = NULL;
1380         GtkWidget *widget;
1381         gint static_button_size;
1382         ModestWindowMgr *mgr;
1383
1384         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1385         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1386         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1387
1388         mgr = modest_runtime_get_window_mgr ();
1389         static_button_size = modest_window_mgr_get_fullscreen_mode (mgr)?118:108;
1390
1391         if (parent_priv->toolbar) {
1392                 /* left size buttons */
1393                 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageNew");
1394                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1395                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1396                 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1397                 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply");
1398                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1399                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1400                 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1401                 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage");
1402                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1403                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1404                 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1405                 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1406                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1407                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1408                 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1409                 
1410                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1411                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1412                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1413                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1414                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1415                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1416                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1417                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1418         }
1419                 
1420 }
1421
1422
1423
1424 static gboolean
1425 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1426 {
1427         if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1428                 ModestWindowPrivate *parent_priv;
1429                 ModestWindowMgr *mgr;
1430                 gboolean is_fullscreen;
1431                 GtkAction *fs_toggle_action;
1432                 gboolean active;
1433                 
1434                 mgr = modest_runtime_get_window_mgr ();
1435                 
1436                 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1437
1438                 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1439                 
1440                 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1441                 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1442                 if (is_fullscreen != active) {
1443                         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1444                 }
1445
1446                 toolbar_resize (MODEST_MAIN_WINDOW (widget));
1447         }
1448
1449         return FALSE;
1450
1451 }
1452
1453 static void 
1454 modest_main_window_show_toolbar (ModestWindow *self,
1455                                  gboolean show_toolbar)
1456 {
1457         ModestMainWindowPrivate *priv = NULL;
1458         ModestWindowPrivate *parent_priv = NULL;        
1459         GtkWidget *reply_button = NULL, *menu = NULL;
1460         GtkWidget *placeholder = NULL;
1461         gint insert_index;
1462         const gchar *action_name;
1463         GtkAction *action;
1464
1465         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1466         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1467         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1468
1469         /* Set optimized view status */
1470         priv->optimized_view = !show_toolbar;
1471
1472         if (!parent_priv->toolbar) {
1473                 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
1474                                                                   "/ToolBar");
1475                 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1476
1477                 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1478                 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1479                 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1480                 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1481                 toolbar_resize (MODEST_MAIN_WINDOW (self));
1482                 
1483                 /* Add ProgressBar (Transfer toolbar) */ 
1484                 priv->progress_bar = modest_progress_bar_widget_new ();
1485                 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1486                 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1487                 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1488                 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1489                 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1490                 
1491                 /* Connect cancel 'clicked' signal to abort progress mode */
1492                 g_signal_connect(priv->cancel_toolitem, "clicked",
1493                                  G_CALLBACK(cancel_progressbar),
1494                                  self);
1495                 
1496                 /* Add it to the observers list */
1497                 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1498
1499                 /* Add to window */
1500                 hildon_window_add_toolbar (HILDON_WINDOW (self), 
1501                                            GTK_TOOLBAR (parent_priv->toolbar));
1502
1503                 /* Set reply button tap and hold menu */
1504                 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
1505                                                           "/ToolBar/ToolbarMessageReply");
1506                 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1507                                                   "/ToolbarReplyCSM");
1508                 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1509
1510                 /* Set send & receive button tap and hold menu */
1511                 update_menus (MODEST_MAIN_WINDOW (self));
1512         }
1513         
1514         if (show_toolbar) {
1515                 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */ 
1516                 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1517                 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1518
1519                 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1520                 if (modest_main_window_transfer_mode_enabled (MODEST_MAIN_WINDOW(self)))
1521                         set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_TRANSFER);
1522                 else
1523                         set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1524         } else {
1525                 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1526
1527         }
1528
1529         /* Update also the actions (to update the toggles in the
1530            menus), we have to do it manually because some other window
1531            of the same time could have changed it (remember that the
1532            toolbar fullscreen mode is shared by all the windows of the
1533            same type */
1534         if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
1535                 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu";
1536         else
1537                 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu";
1538
1539         action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
1540         modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
1541                                                             show_toolbar);
1542 }
1543
1544 static void
1545 on_account_inserted (TnyAccountStore *accoust_store,
1546                      TnyAccount *account,
1547                      gpointer user_data)
1548 {
1549         /* Transport accounts and local ones (MMC and the Local
1550            folders account do now cause menu changes */
1551         if (TNY_IS_STORE_ACCOUNT (account) && 
1552             modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1553                 update_menus (MODEST_MAIN_WINDOW (user_data));
1554 }
1555
1556 static void
1557 on_default_account_changed (ModestAccountMgr* mgr,
1558                             gpointer user_data)
1559 {
1560         update_menus (MODEST_MAIN_WINDOW (user_data));
1561 }
1562
1563 static void
1564 on_account_removed (TnyAccountStore *accoust_store,
1565                      TnyAccount *account,
1566                      gpointer user_data)
1567 {
1568         /* Transport accounts and local ones (MMC and the Local
1569            folders account do now cause menu changes */
1570         if (TNY_IS_STORE_ACCOUNT (account) && 
1571             modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1572                 update_menus (MODEST_MAIN_WINDOW (user_data));
1573 }
1574
1575 static void
1576 on_account_changed (TnyAccountStore *account_store,
1577                     TnyAccount *account,
1578                     gpointer user_data)
1579 {
1580         ModestMainWindow *win = MODEST_MAIN_WINDOW (user_data);
1581         
1582         /* We need to refresh the details widget because it could have changed */
1583         if (modest_main_window_get_contents_style(win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS) {
1584                 modest_main_window_set_contents_style (win, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1585         }
1586
1587         /* Update the menus as well, the account name could be
1588            changed. Transport accounts and local ones (MMC and the
1589            Local folders account do now cause menu changes */
1590         if (TNY_IS_STORE_ACCOUNT (account) && 
1591             modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1592                 update_menus (MODEST_MAIN_WINDOW (user_data));
1593 }
1594
1595 /* 
1596  * This function manages the key events used to navigate between
1597  * header and folder views (when the window is in split view)
1598  *
1599  * FROM         KEY        ACTION
1600  * -------------------------------------------------
1601  * HeaderView   GDK_Left   Move focus to folder view
1602  * FolderView   GDK_Right  Move focus to header view
1603  *
1604  * There is no need to scroll to selected row, the widgets will be the
1605  * responsibles of doing that (probably managing the focus-in event
1606  */
1607 static gboolean 
1608 on_inner_widgets_key_pressed (GtkWidget *widget,
1609                               GdkEventKey *event,
1610                               gpointer user_data)
1611 {
1612         ModestMainWindowPrivate *priv;
1613
1614         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1615
1616         /* Do nothing if we're in SIMPLE style */
1617         if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1618                 return FALSE;
1619
1620         if (MODEST_IS_HEADER_VIEW (widget)) {
1621                 if (event->keyval == GDK_Left)
1622                         gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1623                 else if ((event->keyval == GDK_Return)||(event->keyval == GDK_KP_Enter)) {
1624                         guint selected_headers = modest_header_view_count_selected_headers (MODEST_HEADER_VIEW (widget));
1625                         if (selected_headers > 1) {
1626                                 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1627                                 return TRUE;
1628                         }
1629                 }
1630         } else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1631                 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1632
1633         return FALSE;
1634 }
1635
1636 static void
1637 set_alignment (GtkWidget *widget,
1638                gpointer data)
1639 {
1640         gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1641         gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1642 }
1643
1644 static GtkWidget *
1645 create_empty_view (void)
1646 {
1647         GtkLabel *label = NULL;
1648         GtkWidget *align = NULL;
1649
1650         align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1651         label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1652         gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);      
1653         gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1654
1655         return GTK_WIDGET(align);
1656 }
1657
1658 /*
1659  * Free the returned string
1660  */
1661 static gchar *
1662 get_gray_color_markup (GtkWidget *styled_widget)
1663 {
1664         gchar *gray_color_markup = NULL;
1665 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1666         /* Obtain the secondary text color. We need a realized widget, that's why 
1667            we get styled_widget from outside */
1668         GdkColor color;
1669         if (gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color)) 
1670                 gray_color_markup = modest_text_utils_get_color_string (&color);
1671 #endif /*MODEST_HAVE_HILDON0_WIDGETS*/
1672         
1673         if (!gray_color_markup) 
1674                 gray_color_markup = g_strdup ("#BBBBBB");
1675
1676         return gray_color_markup;
1677 }
1678
1679 /*
1680  * Free the returned string
1681  */
1682 static gchar*
1683 create_device_name_visual_string (const gchar *device_name,
1684                                   const gchar *gray_color_markup)
1685 {
1686         gchar *tmp, *label;
1687
1688         /* We have to use "" to fill the %s of the translation. We can
1689            not just use the device name because the device name is
1690            shown in a different color, so it could not be included
1691            into the <span> tag */
1692         tmp = g_strdup_printf (_("mcen_fi_localroot_description"), "");
1693         label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s", 
1694                                          gray_color_markup, 
1695                                          tmp, 
1696                                          device_name);
1697         g_free (tmp);
1698
1699         return label;
1700 }
1701
1702 static GtkWidget *
1703 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1704 {
1705         /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1706         
1707         GtkWidget *vbox;
1708         GtkWidget *label_w;
1709         gchar *label;
1710         gchar *gray_color_markup;
1711
1712         vbox = gtk_vbox_new (FALSE, 0);
1713
1714         gray_color_markup = get_gray_color_markup (styled_widget);
1715
1716         /* Account description: */
1717         if (modest_tny_account_is_virtual_local_folders (account)
1718                 || (modest_tny_account_is_memory_card_account (account))) {
1719         
1720                 /* Get device name */
1721                 gchar *device_name = NULL;
1722                 if (modest_tny_account_is_virtual_local_folders (account))
1723                         device_name = modest_conf_get_string (modest_runtime_get_conf(),
1724                                                       MODEST_CONF_DEVICE_NAME, NULL);
1725                 else
1726                         device_name = g_strdup (tny_account_get_name (account));
1727
1728                 label = create_device_name_visual_string ((const gchar *) device_name, 
1729                                                           (const gchar *) gray_color_markup);
1730                 label_w = gtk_label_new (NULL);
1731                 gtk_label_set_markup (GTK_LABEL (label_w), label);
1732                 gtk_label_set_ellipsize (GTK_LABEL (label_w),  PANGO_ELLIPSIZE_END);
1733                 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1734                 g_free (device_name);
1735                 g_free (label);
1736         } else {
1737                 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1738                         gtk_box_pack_start (GTK_BOX (vbox), 
1739                                 gtk_label_new (tny_account_get_name (account)), 
1740                                 FALSE, FALSE, 0);
1741                 } else {
1742                         /* Other accounts, such as IMAP and POP: */
1743                         
1744                         GString *proto;
1745                         gchar *tmp;
1746         
1747                         /* Put proto in uppercase */
1748                         proto = g_string_new (tny_account_get_proto (account));
1749                         proto = g_string_ascii_up (proto);
1750                         
1751                         /* note: mcen_fi_localroot_description is something like "%s account"
1752                          * however, we should display "%s account: %s"... therefore, ugly tmp */
1753                         tmp   = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1754                         label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s", 
1755                                                          gray_color_markup, tmp, tny_account_get_name (account));
1756                         g_free (tmp);
1757
1758                         label_w = gtk_label_new (NULL);
1759                         gtk_label_set_markup (GTK_LABEL (label_w), label);
1760                         gtk_label_set_ellipsize (GTK_LABEL (label_w),  PANGO_ELLIPSIZE_END);
1761                         gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1762                         g_string_free (proto, TRUE);
1763                         g_free (label);
1764                 }
1765         }
1766
1767         /* Message count */
1768         TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1769         label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d", 
1770                                          gray_color_markup, _("mcen_fi_rootfolder_messages"), 
1771                                          modest_tny_folder_store_get_message_count (folder_store));
1772         label_w = gtk_label_new (NULL);
1773         gtk_label_set_markup (GTK_LABEL (label_w), label);
1774         gtk_label_set_ellipsize (GTK_LABEL (label_w),  PANGO_ELLIPSIZE_END);
1775         gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1776         g_free (label);
1777
1778         /* Folder count */
1779         label = g_markup_printf_escaped ("<span color='%s'>%s</span>: %d", 
1780                                          gray_color_markup, 
1781                                          _("mcen_fi_rootfolder_folders"), 
1782                                          modest_tny_folder_store_get_folder_count (folder_store));
1783         label_w = gtk_label_new (NULL);
1784         gtk_label_set_markup (GTK_LABEL (label_w), label);
1785         gtk_label_set_ellipsize (GTK_LABEL (label_w),  PANGO_ELLIPSIZE_END);
1786         gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1787         g_free (label);
1788
1789         /* Size / Date */
1790         if (modest_tny_account_is_virtual_local_folders (account)
1791                 || modest_tny_account_is_memory_card_account (account)) {
1792
1793                 gchar *size = modest_text_utils_get_display_size (
1794                         modest_tny_folder_store_get_local_size (folder_store));
1795                 
1796                 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s", 
1797                                                  gray_color_markup, _("mcen_fi_rootfolder_size"),
1798                                                  size);
1799                 g_free (size);
1800                 
1801                 label_w = gtk_label_new (NULL);
1802                 gtk_label_set_markup (GTK_LABEL (label_w), label);
1803                 gtk_label_set_ellipsize (GTK_LABEL (label_w),  PANGO_ELLIPSIZE_END);
1804                 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1805                 g_free (label);
1806         } else if (TNY_IS_ACCOUNT(folder_store)) {
1807                 TnyAccount *account = TNY_ACCOUNT(folder_store);
1808                 
1809                 time_t last_updated;
1810                 const gchar *last_updated_string;
1811                 /* Get last updated from configuration */
1812                 last_updated = modest_account_mgr_get_last_updated (modest_runtime_get_account_mgr (), 
1813                                                                     tny_account_get_id (account));
1814
1815                 if (last_updated > 0) 
1816                         last_updated_string = modest_text_utils_get_display_date(last_updated);
1817                 else
1818                         last_updated_string = g_strdup (_("mcen_va_never"));
1819
1820                 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s", 
1821                                                  gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1822                 label_w = gtk_label_new (NULL);
1823                 gtk_label_set_markup (GTK_LABEL (label_w), label);
1824                 gtk_label_set_ellipsize (GTK_LABEL (label_w),  PANGO_ELLIPSIZE_END);
1825                 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1826                 g_free (label);
1827         }
1828
1829         g_free (gray_color_markup);
1830
1831         /* Set alignment */
1832         gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1833
1834         return vbox;
1835 }
1836
1837 gboolean
1838 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1839 {
1840         ModestMainWindowPrivate *priv = NULL;
1841         
1842         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1843
1844         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1845
1846         return priv->send_receive_in_progress;
1847 }
1848
1849 void 
1850 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1851 {
1852         GtkAction *action = NULL;
1853         GtkWidget *widget = NULL;
1854         ModestMainWindowPrivate *priv = NULL;
1855                 
1856         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1857         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1858         
1859         priv->send_receive_in_progress  = TRUE;
1860
1861         action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu"); 
1862         gtk_action_set_sensitive (action, FALSE);
1863 /*         action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1864 /*      gtk_action_set_sensitive (action, FALSE); */
1865         widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");       
1866         gtk_widget_set_sensitive (widget, FALSE);
1867
1868
1869 void 
1870 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1871 {
1872         GtkAction *action = NULL;
1873         GtkWidget *widget = NULL;
1874         ModestMainWindowPrivate *priv = NULL;
1875                 
1876         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1877         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1878
1879         priv->send_receive_in_progress  = FALSE;
1880
1881         action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu"); 
1882         gtk_action_set_sensitive (action, TRUE);
1883 /*         action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu");     */
1884 /*      gtk_action_set_sensitive (action, TRUE); */
1885         widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");       
1886         gtk_widget_set_sensitive (widget, TRUE);
1887
1888
1889
1890 static void
1891 on_msg_count_changed (ModestHeaderView *header_view,
1892                       TnyFolder *folder,
1893                       TnyFolderChange *change,
1894                       ModestMainWindow *main_window)
1895 {
1896         gboolean folder_empty = FALSE;
1897         gboolean all_marked_as_deleted = FALSE;
1898         ModestMainWindowPrivate *priv;
1899
1900         g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1901         g_return_if_fail (TNY_IS_FOLDER(folder));
1902         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
1903
1904         if (change != NULL) {
1905                 TnyFolderChangeChanged changed;
1906
1907                 changed = tny_folder_change_get_changed (change);
1908                 /* If something changes */
1909                 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1910                         folder_empty = (((guint) tny_folder_change_get_new_all_count (change)) == 0);
1911                 else
1912                         folder_empty = (((guint) tny_folder_get_all_count (TNY_FOLDER (folder))) == 0);
1913
1914                 /* Play a sound (if configured) and make the LED blink  */
1915                 if (changed & TNY_FOLDER_CHANGE_CHANGED_ADDED_HEADERS) {
1916                         modest_platform_on_new_headers_received (NULL, FALSE);
1917                 }
1918         }
1919
1920         /* Check if all messages are marked to be deleted */
1921         all_marked_as_deleted = modest_header_view_is_empty (header_view);
1922         folder_empty = folder_empty || all_marked_as_deleted;
1923
1924         /* Set contents style of headers view */
1925         if (folder_empty)  {
1926                 modest_main_window_set_contents_style (main_window,
1927                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1928                 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1929         } else {
1930                 modest_main_window_set_contents_style (main_window,
1931                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1932         }
1933 }
1934
1935
1936 void 
1937 modest_main_window_set_contents_style (ModestMainWindow *self, 
1938                                        ModestMainWindowContentsStyle style)
1939 {
1940         ModestMainWindowPrivate *priv;
1941
1942         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1943
1944         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1945
1946         /* We allow to set the same content style than the previously
1947            set if there are details, because it could happen when we're
1948            selecting different accounts consecutively */
1949         if ((priv->contents_style == style) &&
1950             (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1951                 return;
1952
1953         /* Remove previous child. Delete it if it was an account
1954            details widget */
1955         GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1956         if (content) {
1957                 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1958                         g_object_ref (content);
1959                 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1960                         g_object_ref (priv->empty_view);
1961                         gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
1962                 }
1963                 
1964                 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1965         }
1966
1967         priv->contents_style = style;
1968
1969         switch (priv->contents_style) {
1970         case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1971                 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1972                 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1973                                                       TRUE);
1974                 break;
1975         case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1976         {
1977                 /* if we're started without main win, there may not be a folder
1978                  * view. this fixes a GLib-Critical */
1979                 if (priv->folder_view) {
1980                         TnyFolderStore *selected_folderstore = 
1981                                 modest_folder_view_get_selected (priv->folder_view);
1982                         if (TNY_IS_ACCOUNT (selected_folderstore)) {    
1983                                 priv->details_widget = create_details_widget (GTK_WIDGET (self),
1984                                                                 TNY_ACCOUNT (selected_folderstore));
1985                                 
1986                                 wrap_in_scrolled_window (priv->contents_widget, 
1987                                                          priv->details_widget);
1988                         }
1989                         g_object_unref (selected_folderstore);
1990                         modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1991                                                               FALSE);
1992                 }
1993                 break;
1994         }
1995         case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
1996                 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
1997                 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1998                                                       FALSE);
1999                 break;
2000         default:
2001                 g_return_if_reached ();
2002         }
2003
2004         /* Show */
2005         gtk_widget_show_all (priv->contents_widget);
2006 }
2007
2008 ModestMainWindowContentsStyle
2009 modest_main_window_get_contents_style (ModestMainWindow *self)
2010 {
2011         ModestMainWindowPrivate *priv;
2012
2013         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
2014
2015         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2016         return priv->contents_style;
2017 }
2018
2019
2020 static void 
2021 on_configuration_key_changed (ModestConf* conf, 
2022                               const gchar *key, 
2023                               ModestConfEvent event,
2024                               ModestConfNotificationId id, 
2025                               ModestMainWindow *self)
2026 {
2027         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2028         TnyAccount *account = NULL;
2029
2030         if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
2031                 return;
2032
2033         if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
2034                 return;
2035
2036         if (priv->folder_view) 
2037                 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
2038
2039         if (account && TNY_IS_ACCOUNT (account) &&
2040             strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID) == 0) {
2041                 GList *children;
2042                 GtkLabel *label;
2043                 const gchar *device_name;
2044                 gchar *new_text, *gray_color_markup;
2045                 
2046                 /* Get label */
2047                 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
2048                 label = GTK_LABEL (children->data);
2049                 
2050                 device_name = modest_conf_get_string (modest_runtime_get_conf(),
2051                                                       MODEST_CONF_DEVICE_NAME, NULL);
2052
2053                 gray_color_markup = get_gray_color_markup (GTK_WIDGET (self));          
2054                 new_text = create_device_name_visual_string (device_name, gray_color_markup);
2055                 
2056                 gtk_label_set_markup (label, new_text);
2057                 gtk_widget_show (GTK_WIDGET (label));
2058                 
2059                 g_free (gray_color_markup);
2060                 g_free (new_text);
2061                 g_list_free (children);
2062         }
2063         g_object_unref (account);
2064 }
2065
2066 static gboolean
2067 set_toolbar_transfer_mode (ModestMainWindow *self)
2068 {
2069         ModestMainWindowPrivate *priv = NULL;
2070         
2071         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2072
2073         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2074
2075         set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
2076         
2077         if (priv->progress_bar_timeout > 0) {
2078                 g_source_remove (priv->progress_bar_timeout);
2079                 priv->progress_bar_timeout = 0;
2080         }
2081
2082         return FALSE;
2083 }
2084
2085 static void 
2086 set_toolbar_mode (ModestMainWindow *self, 
2087                   ModestToolBarModes mode)
2088 {
2089         ModestWindowPrivate *parent_priv = NULL;
2090         ModestMainWindowPrivate *priv = NULL;
2091         GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
2092         
2093         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
2094
2095         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2096         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2097
2098         /* In case this was called before the toolbar exists: */
2099         if (!(parent_priv->toolbar))
2100                 return;
2101
2102         g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar)); 
2103         
2104         sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
2105         refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
2106         cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
2107
2108         /* Sets current toolbar mode */
2109         priv->current_toolbar_mode = mode;
2110
2111         /* Checks the dimming rules */
2112         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2113
2114         /* Show and hide toolbar items */
2115         switch (mode) {
2116         case TOOLBAR_MODE_NORMAL:
2117                 if (sort_action)
2118                         gtk_action_set_visible (sort_action, TRUE);
2119                 if (refresh_action)
2120                         gtk_action_set_visible (refresh_action, TRUE);
2121                 if (priv->progress_toolitem) {
2122                         gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
2123                         gtk_widget_hide (priv->progress_toolitem);
2124                 }
2125                 if (priv->progress_bar)
2126                         gtk_widget_hide (priv->progress_bar);
2127                 
2128                 if (cancel_action)
2129                         gtk_action_set_visible (cancel_action, FALSE);
2130
2131                 /* Hide toolbar if optimized view is enabled */
2132                 if (priv->optimized_view)
2133                         gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
2134                 break;
2135         case TOOLBAR_MODE_TRANSFER:
2136                 if (sort_action)
2137                         gtk_action_set_visible (sort_action, FALSE);
2138                 if (refresh_action)
2139                         gtk_action_set_visible (refresh_action, FALSE);
2140                 if (cancel_action)
2141                         gtk_action_set_visible (cancel_action, TRUE);
2142                 if (priv->progress_bar)
2143                         gtk_widget_show (priv->progress_bar);
2144                 if (priv->progress_toolitem) {
2145                         gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
2146                         gtk_widget_show (priv->progress_toolitem);
2147                 }
2148
2149                 /* Show toolbar if it's hiden (optimized view ) */
2150                 if (priv->optimized_view)
2151                         gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2152                 break;
2153         default:
2154                 g_return_if_reached ();
2155         }
2156 }
2157
2158 gboolean
2159 modest_main_window_transfer_mode_enabled (ModestMainWindow *self)
2160 {
2161         ModestMainWindowPrivate *priv;
2162
2163         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2164         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2165
2166         return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
2167 }
2168
2169 static void
2170 cancel_progressbar (GtkToolButton *toolbutton,
2171                     ModestMainWindow *self)
2172 {
2173         GSList *tmp;
2174         ModestMainWindowPrivate *priv;
2175         
2176         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2177
2178         /* Get operation observers and cancel all the operations */
2179         tmp = priv->progress_widgets;
2180         while (tmp) {
2181                 modest_progress_object_cancel_all_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2182                 tmp=g_slist_next(tmp);
2183         }
2184 }
2185
2186 static gboolean
2187 observers_empty (ModestMainWindow *self)
2188 {
2189         GSList *tmp = NULL;
2190         ModestMainWindowPrivate *priv;
2191         gboolean is_empty = TRUE;
2192         guint pending_ops = 0;
2193  
2194         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2195         tmp = priv->progress_widgets;
2196
2197         /* Check all observers */
2198         while (tmp && is_empty)  {
2199                 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2200                 is_empty = pending_ops == 0;
2201                 
2202                 tmp = g_slist_next(tmp);
2203         }
2204         
2205         return is_empty;
2206 }
2207
2208
2209 /**
2210  * Gets the toolbar mode needed for each mail operation. It stores in
2211  * @mode_changed if the toolbar mode has changed or not
2212  */
2213 static ModestToolBarModes
2214 get_toolbar_mode_from_mail_operation (ModestMainWindow *self,
2215                                       ModestMailOperation *mail_op,
2216                                       gboolean *mode_changed)
2217 {
2218         ModestToolBarModes mode;
2219         ModestMainWindowPrivate *priv;
2220
2221         *mode_changed = FALSE;
2222         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2223
2224         /* Get toolbar mode from operation id*/
2225         switch (modest_mail_operation_get_type_operation (mail_op)) {
2226         case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
2227         case MODEST_MAIL_OPERATION_TYPE_OPEN:
2228                 mode = TOOLBAR_MODE_TRANSFER;
2229                 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
2230                         *mode_changed = TRUE;
2231                 break;
2232         default:
2233                 mode = TOOLBAR_MODE_NORMAL;             
2234         }
2235         return mode;
2236 }
2237
2238 static void 
2239 on_mail_operation_started (ModestMailOperation *mail_op,
2240                            gpointer user_data)
2241 {
2242         ModestMainWindow *self;
2243         ModestMailOperationTypeOperation op_type;
2244         ModestMainWindowPrivate *priv;
2245         ModestToolBarModes mode;
2246         GSList *tmp;
2247         gboolean mode_changed = FALSE;
2248         TnyAccount *account;
2249
2250         self = MODEST_MAIN_WINDOW (user_data);
2251         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2252
2253         /* Do not show progress for receiving operations if the
2254            account is the local account or the MMC one */
2255         op_type = modest_mail_operation_get_type_operation (mail_op);
2256         account = modest_mail_operation_get_account (mail_op);
2257         if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2258                 gboolean is_remote;
2259
2260                 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2261                               modest_tny_account_is_memory_card_account (account));
2262                 g_object_unref (account);
2263                 if (!is_remote)
2264                         return;
2265         }
2266                
2267         /* Get toolbar mode from operation id*/
2268         mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2269
2270         /* Add operation observers and change toolbar if neccessary*/
2271         tmp = priv->progress_widgets;
2272         if (mode == TOOLBAR_MODE_TRANSFER) {
2273                 if (mode_changed) {
2274                         GObject *source = modest_mail_operation_get_source(mail_op);
2275                         if (G_OBJECT (self) == source) {
2276                                 set_toolbar_transfer_mode(self);
2277                         }
2278                         g_object_unref (source);
2279                 }
2280
2281                 while (tmp) {
2282                         modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2283                                                               mail_op);
2284                         tmp = g_slist_next (tmp);
2285                 }
2286         }
2287 }
2288
2289 static void 
2290 on_mail_operation_finished (ModestMailOperation *mail_op,
2291                             gpointer user_data)
2292 {
2293         ModestToolBarModes mode;
2294         ModestMailOperationTypeOperation op_type;
2295         GSList *tmp = NULL;
2296         ModestMainWindow *self;
2297         gboolean mode_changed;
2298         TnyAccount *account;
2299         ModestMainWindowPrivate *priv;
2300
2301         self = MODEST_MAIN_WINDOW (user_data);
2302         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2303
2304         /* The mail operation was not added to the progress objects if
2305            the account was the local account or the MMC one */
2306         op_type = modest_mail_operation_get_type_operation (mail_op);
2307         account = modest_mail_operation_get_account (mail_op);
2308         if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2309                 gboolean is_remote;
2310
2311                 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2312                               modest_tny_account_is_memory_card_account (account));
2313                 g_object_unref (account);
2314                 if (!is_remote)
2315                         return;
2316         }
2317
2318         /* Get toolbar mode from operation id*/
2319         mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2320
2321         /* Change toolbar mode */
2322         tmp = priv->progress_widgets;
2323         if (mode == TOOLBAR_MODE_TRANSFER) {                    
2324                 while (tmp) {
2325                         modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2326                                                                  mail_op);
2327                         tmp = g_slist_next (tmp);
2328                 }
2329                 
2330                 /* If no more operations are being observed, NORMAL mode is enabled again */
2331                 if (observers_empty (self)) {
2332                         set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);                           
2333                 }
2334         }
2335 }
2336
2337 static void
2338 on_queue_changed (ModestMailOperationQueue *queue,
2339                   ModestMailOperation *mail_op,
2340                   ModestMailOperationQueueNotification type,
2341                   ModestMainWindow *self)
2342 {
2343         ModestMainWindowPrivate *priv;
2344
2345         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2346
2347         if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
2348                 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2349                                                                G_OBJECT (mail_op),
2350                                                                "operation-started",
2351                                                                G_CALLBACK (on_mail_operation_started),
2352                                                                self);
2353                 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2354                                                                G_OBJECT (mail_op),
2355                                                                "operation-finished",
2356                                                                G_CALLBACK (on_mail_operation_finished),
2357                                                                self);
2358         } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
2359                 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2360                                                                   G_OBJECT (mail_op),
2361                                                                   "operation-started");
2362                 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2363                                                                   G_OBJECT (mail_op),
2364                                                                   "operation-finished");
2365         }
2366 }
2367
2368 static void
2369 set_account_visible(ModestMainWindow *self, const gchar *acc_name)
2370 {
2371         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2372         GtkAction *action;
2373         ModestAccountMgr *mgr;
2374         ModestAccountSettings *settings;
2375         ModestServerAccountSettings *store_settings = NULL;
2376
2377         /* Get account data */
2378         mgr = modest_runtime_get_account_mgr ();
2379         settings = modest_account_mgr_load_account_settings (mgr, acc_name);
2380         if (settings)
2381                 store_settings = modest_account_settings_get_store_settings (settings);
2382
2383         /* Set the new visible & active account */
2384         if (settings && (modest_server_account_settings_get_account_name (store_settings)!= NULL)) { 
2385                 const gchar *account_name;
2386
2387                 account_name = modest_account_settings_get_account_name (settings);
2388
2389                 modest_folder_view_set_account_id_of_visible_server_account 
2390                         (priv->folder_view,
2391                          modest_server_account_settings_get_account_name (store_settings));
2392                 modest_window_set_active_account (MODEST_WINDOW (self), account_name);
2393                 action = gtk_action_group_get_action (priv->view_additions_group, account_name);
2394                 if (action != NULL) {
2395                         if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
2396                                 modest_utils_toggle_action_set_active_block_notify (
2397                                         GTK_TOGGLE_ACTION (action),
2398                                         TRUE);
2399                         }
2400                 }
2401         }
2402         
2403         modest_folder_view_select_first_inbox_or_local (priv->folder_view);
2404
2405
2406         /* Free */
2407         if (settings) {
2408                 g_object_unref (store_settings);
2409                 g_object_unref (settings);
2410         }
2411 }
2412
2413 /* Make sure that at least one account is "viewed": */
2414 static void
2415 set_at_least_one_account_visible(ModestMainWindow *self)
2416 {
2417         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2418         ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2419
2420         if (!(priv->folder_view)) {
2421                 /* It is too early to do this. */
2422                 return; 
2423         }
2424         
2425         const gchar *active_server_account_name = 
2426                 modest_folder_view_get_account_id_of_visible_server_account (priv->folder_view);
2427         
2428         if (!active_server_account_name ||
2429                 !modest_account_mgr_account_exists (account_mgr, active_server_account_name, TRUE))
2430         {
2431                 gchar* first_modest_name = modest_account_mgr_get_first_account_name (account_mgr);
2432                 gchar* default_modest_name = modest_account_mgr_get_default_account (account_mgr);
2433                 if (default_modest_name) {
2434                         set_account_visible (self, default_modest_name);
2435                 } else if (first_modest_name) {
2436                         set_account_visible (self, first_modest_name);
2437                 }
2438                 g_free (first_modest_name);
2439                 g_free (default_modest_name);
2440         }
2441 }
2442
2443 static void 
2444 on_show_account_action_toggled  (GtkToggleAction *action,
2445                                    gpointer user_data)
2446 {
2447         ModestMainWindow *self = MODEST_MAIN_WINDOW (user_data);
2448
2449         const gchar *acc_name = gtk_action_get_name (GTK_ACTION (action));
2450         if (gtk_toggle_action_get_active (action))
2451                 set_account_visible (self, acc_name);
2452 }
2453
2454 static void
2455 refresh_account (const gchar *account_name)
2456 {
2457         ModestWindow *win;
2458         
2459         /* win must already exists here, obviously */ 
2460         win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
2461                                                  FALSE);
2462         if (!win) {
2463                 g_warning ("%s: BUG: no main window!", __FUNCTION__);
2464                 return;
2465         }
2466         
2467         /* If account_name == NULL, we must update all (option All) */
2468         if (!account_name)
2469                 modest_ui_actions_do_send_receive_all (win, FALSE);
2470         else
2471                 modest_ui_actions_do_send_receive (account_name, FALSE, win);
2472         
2473 }
2474
2475 static void 
2476 on_refresh_account_action_activated  (GtkAction *action,
2477                                       gpointer user_data)
2478 {
2479         refresh_account ((const gchar*) user_data);
2480 }
2481
2482 static void
2483 on_send_receive_csm_activated (GtkMenuItem *item,
2484                                gpointer user_data)
2485 {
2486         refresh_account ((const gchar*) user_data);
2487 }
2488
2489 static gboolean
2490 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2491 {
2492         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2493
2494         hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2495         return FALSE;
2496
2497 }
2498
2499 static gboolean
2500 on_folder_view_focus_in (GtkWidget *widget, GdkEventFocus *event, gpointer userdata)
2501 {
2502         ModestMainWindow *main_window = NULL;
2503         
2504         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2505         main_window = MODEST_MAIN_WINDOW (userdata);
2506         
2507         /* Update toolbar dimming state */
2508         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2509
2510         return FALSE;
2511 }
2512
2513 static gboolean
2514 on_header_view_focus_in (GtkWidget *widget,
2515                          GdkEventFocus *event,
2516                          gpointer userdata)
2517 {
2518         ModestMainWindow *main_window = NULL;
2519
2520         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2521
2522         main_window = MODEST_MAIN_WINDOW (userdata);
2523
2524         /* Update toolbar dimming state */
2525         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2526
2527         return FALSE;
2528 }
2529
2530 static void 
2531 on_folder_selection_changed (ModestFolderView *folder_view,
2532                              TnyFolderStore *folder_store, 
2533                              gboolean selected,
2534                              ModestMainWindow *main_window)
2535 {
2536         ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (main_window);
2537         GtkAction *action = NULL;
2538         gboolean show_reply = TRUE;
2539         gboolean show_forward = TRUE;
2540         gboolean show_cancel_send = FALSE;
2541         gboolean show_clipboard = TRUE;
2542         gboolean show_delete = TRUE;
2543
2544         if (selected) {
2545                 if (TNY_IS_ACCOUNT (folder_store)) {
2546                         show_reply = show_forward = show_cancel_send = show_clipboard = show_delete = FALSE;
2547                 } else if (TNY_IS_FOLDER (folder_store)) {
2548                         if (modest_tny_folder_is_local_folder (TNY_FOLDER (folder_store))) {
2549                                 TnyFolderType folder_type = modest_tny_folder_get_local_or_mmc_folder_type (
2550                                         TNY_FOLDER (folder_store));
2551                                 switch (folder_type) {
2552                                 case TNY_FOLDER_TYPE_DRAFTS:
2553                                         show_clipboard = show_delete = TRUE;
2554                                         show_reply = show_forward = show_cancel_send = FALSE;
2555                                         break;
2556                                 case TNY_FOLDER_TYPE_SENT:
2557                                         show_forward = show_clipboard = show_delete = TRUE;
2558                                         show_reply = show_cancel_send = FALSE;
2559                                         break;
2560                                 case TNY_FOLDER_TYPE_OUTBOX:
2561                                         show_clipboard = show_delete = show_cancel_send = TRUE;
2562                                         show_reply = show_forward = FALSE;
2563                                         break;
2564                                 case TNY_FOLDER_TYPE_INVALID:
2565                                         g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
2566                                         break;
2567                                 default:
2568                                         show_reply = show_forward = show_clipboard = show_delete = TRUE;
2569                                         show_cancel_send = FALSE;
2570                                 }
2571                         } else {
2572                                 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2573                                 show_cancel_send = FALSE;
2574                         }
2575                 }
2576         }
2577
2578         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReply");
2579         gtk_action_set_visible (action, show_reply);
2580         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReplyAll");
2581         gtk_action_set_visible (action, show_reply);
2582         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMForward");
2583         gtk_action_set_visible (action, show_forward);
2584         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCancelSending");
2585         gtk_action_set_visible (action, show_cancel_send);
2586         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMDelete");
2587         gtk_action_set_visible (action, show_delete);
2588
2589         /* We finally call to the ui actions handler, after updating properly
2590          * the header view CSM */
2591         modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window);
2592 }
2593
2594 gboolean 
2595 modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window,
2596                                                    GtkTreeModel *model,
2597                                                    GtkTreeRowReference *row_reference,
2598                                                    ModestMainWindow *self)
2599 {
2600         ModestMainWindowPrivate *priv = NULL;
2601         GtkTreeModel *header_model = NULL;
2602         GtkTreePath *path = NULL;
2603
2604         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (view_window), FALSE);
2605         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2606         g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE);
2607
2608         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2609         header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->header_view));
2610
2611         /* Do nothing if we changed the folder in the main view */
2612         if (header_model != model)
2613                 return FALSE;
2614
2615         /* Select the message in the header view */
2616         path = gtk_tree_row_reference_get_path (row_reference);
2617         gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->header_view),
2618                                   path, NULL, FALSE);
2619         gtk_tree_path_free (path);
2620
2621         return TRUE;
2622 }
2623
2624 static gboolean
2625 show_updating_banner (gpointer user_data)
2626 {
2627         ModestMainWindowPrivate *priv = NULL;
2628
2629         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2630
2631         if (priv->updating_banner == NULL) {
2632
2633                 /* We're outside the main lock */
2634                 gdk_threads_enter ();
2635                 priv->updating_banner = 
2636                         modest_platform_animation_banner (GTK_WIDGET (user_data), NULL,
2637                                                           _CS ("ckdg_pb_updating"));
2638                 gdk_threads_leave ();
2639         }
2640
2641         /* Remove timeout */
2642         priv->updating_banner_timeout = 0;
2643         return FALSE;
2644 }
2645
2646 /**
2647  * We use this function to show/hide a progress banner showing
2648  * "Updating" while the header view is being filled. We're not showing
2649  * it unless the update takes more than 2 seconds
2650  *
2651  * If starting = TRUE then the refresh is starting, otherwise it means
2652  * that is has just finished
2653  */
2654 static void 
2655 on_updating_msg_list (ModestHeaderView *header_view,
2656                       gboolean starting,
2657                       gpointer user_data)
2658 {
2659         ModestMainWindowPrivate *priv = NULL;
2660
2661         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2662         
2663         /* Remove old timeout */
2664         if (priv->updating_banner_timeout > 0) {
2665                 g_source_remove (priv->updating_banner_timeout);
2666                 priv->updating_banner_timeout = 0;
2667         }
2668
2669         /* Create a new timeout */
2670         if (starting) {
2671                 priv->updating_banner_timeout = 
2672                         g_timeout_add (2000, show_updating_banner, user_data);
2673         } else {
2674                 /* Remove the banner if exists */
2675                 if (priv->updating_banner) {
2676                         gtk_widget_destroy (priv->updating_banner);
2677                         priv->updating_banner = NULL;
2678                 }
2679         }
2680 }
2681
2682 gboolean
2683 modest_main_window_screen_is_on (ModestMainWindow *self)
2684 {
2685         ModestMainWindowPrivate *priv = NULL;
2686
2687         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2688         
2689         return (priv->display_state == OSSO_DISPLAY_ON) ? TRUE : FALSE;
2690 }