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