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