* Added msg-changed signal to the viewer window, to notify about the change in the...
[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 #include "widgets/modest-header-view-priv.h"
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, G_CALLBACK (modest_ui_actions_cancel_send) },
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 (err) {
487                 printf ("DEBUG: %s: err->code=%d, err->message=%s\n", __FUNCTION__, err->code, err->message);
488         }
489
490         if (header) {
491                 gchar *str = g_strdup_printf ("%s. Do you want to remove the message (%s)?",
492                         err->message, tny_header_get_subject (header));
493                 OnResponseInfo *info = g_slice_new (OnResponseInfo);
494                 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (user_data), 0,
495                         GTK_MESSAGE_ERROR, GTK_BUTTONS_YES_NO, str);
496                 g_free (str);
497                 info->queue = g_object_ref (self);
498                 info->self = g_object_ref (user_data);
499                 info->header = g_object_ref (header);
500                 g_signal_connect (G_OBJECT (dialog), "response",
501                         G_CALLBACK (on_response), info);
502                 gtk_widget_show_all (dialog);
503         }
504 }
505
506 typedef struct {
507         TnySendQueue *queue;
508         guint signal;
509 } QueueErrorSignal;
510
511 static void
512 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
513 {
514         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
515
516         GList *oerrsignals = priv->queue_err_signals;
517         while (oerrsignals) {
518                 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
519                 g_signal_handler_disconnect (esignal->queue, esignal->signal);
520                 g_slice_free (QueueErrorSignal, esignal);
521                 oerrsignals = g_list_next (oerrsignals);
522         }
523         g_list_free (priv->queue_err_signals);
524         priv->queue_err_signals = NULL;
525 }
526
527 static void
528 on_account_store_connecting_finished (TnyAccountStore *store, ModestMainWindow *self)
529 {
530         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
531
532         /* When going online, do the equivalent of pressing the send/receive button, 
533          * as per the specification:
534          * (without the check for >0 accounts, though that is not specified): */
535
536         TnyDevice *device = tny_account_store_get_device (store);
537
538         /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (priv->folder_view), store); */
539         
540         /* Check that we are really online.
541          * This signal should not be emitted when we are not connected, 
542          * but it seems to happen sometimes: */
543          if (!tny_device_is_online (device))
544                 return;
545                 
546         const gchar *iap_id = tny_maemo_conic_device_get_current_iap_id (TNY_MAEMO_CONIC_DEVICE (device));
547         printf ("DEBUG: %s: connection id=%s\n", __FUNCTION__, iap_id);
548         
549         /* Stop the existing send queues: */
550         modest_runtime_remove_all_send_queues ();
551         
552         /* Create the send queues again, using the appropriate transport accounts 
553          * for this new connection.
554          * This could be the first time that they are created if this is the first 
555          * connection. */
556         /* TODO: Does this really destroy the TnySendQueues and their threads
557          * We do not want 2 TnySendQueues to exist with the same underlying 
558          * outbox directory. */
559
560         modest_main_window_cleanup_queue_error_signals (self);
561
562         GSList *account_names = modest_account_mgr_account_names (
563                 modest_runtime_get_account_mgr(), 
564                 TRUE /* enabled accounts only */);
565         GSList *iter = account_names;
566         while (iter) {
567                 const gchar *account_name = (const gchar*)(iter->data);
568                         if (account_name) {
569                         TnyTransportAccount *account = TNY_TRANSPORT_ACCOUNT (
570                                 modest_tny_account_store_get_transport_account_for_open_connection
571                                                  (modest_runtime_get_account_store(), account_name));
572                         if (account) {
573                                 /* Q: Is this the first location where the send-queues are requested? */
574                                 QueueErrorSignal *esignal = g_slice_new (QueueErrorSignal);
575                                 printf ("debug: %s:\n  Transport account for %s: %s\n", __FUNCTION__, account_name, 
576                                         tny_account_get_id(TNY_ACCOUNT(account)));
577                                 esignal->queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (account));
578                                 esignal->signal = g_signal_connect (G_OBJECT (esignal->queue), "error-happened",
579                                         G_CALLBACK (on_sendqueue_error_happened), self);
580                                 priv->queue_err_signals = g_list_prepend (priv->queue_err_signals, esignal);
581                         }
582                 }
583                 
584                 iter = g_slist_next (iter);
585         }
586
587         modest_account_mgr_free_account_names (account_names);
588         account_names = NULL;
589         
590         modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (self));
591 }
592
593 static void
594 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
595 {
596         g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
597
598         /* Update dimmed */     
599         modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");  
600 }
601
602 static void
603 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
604 {
605         g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
606
607         /* Update visibility */
608
609         /* Update dimmed */     
610         modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");  
611 }
612
613 static void
614 connect_signals (ModestMainWindow *self)
615 {       
616         ModestWindowPrivate *parent_priv;
617         ModestMainWindowPrivate *priv;
618         GtkWidget *menu;
619         
620         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
621         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
622
623         /* folder view */
624         g_signal_connect (G_OBJECT(priv->folder_view), "key-press-event",
625                           G_CALLBACK(on_inner_widgets_key_pressed), self);
626         g_signal_connect (G_OBJECT(priv->folder_view), "folder_selection_changed",
627                           G_CALLBACK(modest_main_window_on_folder_selection_changed), self);
628         g_signal_connect (G_OBJECT(priv->folder_view), "folder-display-name-changed",
629                           G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
630         g_signal_connect (G_OBJECT (priv->folder_view), "focus-in-event", 
631                           G_CALLBACK (on_folder_view_focus_in), self);
632
633         /* Folder view CSM */
634         menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
635         gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
636         g_signal_connect (G_OBJECT(priv->folder_view), "tap-and-hold",
637                           G_CALLBACK(_folder_view_csm_menu_activated),
638                           self);
639         /* header view */
640         g_signal_connect (G_OBJECT(priv->header_view), "header_selected",
641                           G_CALLBACK(modest_ui_actions_on_header_selected), self);
642         g_signal_connect (G_OBJECT(priv->header_view), "header_activated",
643                           G_CALLBACK(modest_ui_actions_on_header_activated), self);
644         g_signal_connect (G_OBJECT(priv->header_view), "item_not_found",
645                           G_CALLBACK(modest_ui_actions_on_item_not_found), self);
646         g_signal_connect (G_OBJECT(priv->header_view), "key-press-event",
647                           G_CALLBACK(on_inner_widgets_key_pressed), self);
648         g_signal_connect (G_OBJECT(priv->header_view), "msg_count_changed",
649                           G_CALLBACK(_on_msg_count_changed), self);
650         g_signal_connect (G_OBJECT (priv->header_view), "focus-in-event",
651                           G_CALLBACK (on_header_view_focus_in), self);
652
653         /* Header view CSM */
654         menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
655         gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
656         g_signal_connect (G_OBJECT(priv->header_view), "tap-and-hold",
657                           G_CALLBACK(_header_view_csm_menu_activated),
658                           self);
659         
660         /* window */
661 /*      g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self); */
662         g_signal_connect (G_OBJECT (self), "window-state-event",
663                           G_CALLBACK (modest_main_window_window_state_event),
664                           NULL);
665         
666         /* Mail Operation Queue */
667         priv->queue_changed_handler_uid = 
668                 g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
669                                   "queue-changed", G_CALLBACK (on_queue_changed), self);
670
671         /* Track changes in the device name */
672         g_signal_connect (G_OBJECT(modest_runtime_get_conf ()),
673                           "key_changed", G_CALLBACK (on_configuration_key_changed), 
674                           self);
675
676         /* Track account changes. We need to refresh the toolbar */
677         g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
678                           "account_update", G_CALLBACK (on_account_update),
679                           self);
680
681         /* Account store */
682         g_signal_connect (G_OBJECT (modest_runtime_get_account_store()), 
683                           "password_requested",
684                           G_CALLBACK (modest_ui_actions_on_password_requested), self);
685                           
686         /* Device */
687         g_signal_connect (G_OBJECT(modest_runtime_get_account_store()), 
688                           "connecting-finished",
689                           G_CALLBACK(on_account_store_connecting_finished), self);
690 }
691
692 #if 0
693 /** Idle handler, to send/receive at startup .*/
694 gboolean
695 sync_accounts_cb (ModestMainWindow *win)
696 {
697         modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (win));
698         return FALSE; /* Do not call this idle handler again. */
699 }
700 #endif
701
702 static void on_hildon_program_is_topmost_notify(GObject *self,
703         GParamSpec *propert_param, gpointer user_data)
704 {
705         HildonProgram *app = HILDON_PROGRAM (self);
706         
707         /*
708         ModestWindow* self = MODEST_WINDOW(user_data);
709         */
710         
711         /* Note that use of hildon_program_set_can_hibernate() 
712          * is generally referred to as "setting the killable flag", 
713          * though hibernation does not seem equal to death.
714          * murrayc */
715                  
716         if (hildon_program_get_is_topmost (app)) {
717                 /* Prevent hibernation when the progam comes to the foreground,
718                  * because hibernation should only happen when the application 
719                  * is in the background: */
720                 hildon_program_set_can_hibernate (app, FALSE);
721         } else {
722                 /* Allow hibernation if the program has gone to the background: */
723                 
724                 /* However, prevent hibernation while the settings are being changed: */
725                 const gboolean hibernation_prevented = 
726                         modest_window_mgr_get_hibernation_is_prevented (
727         modest_runtime_get_window_mgr ()); 
728         
729                 if (hibernation_prevented)
730                         hildon_program_set_can_hibernate (app, FALSE);
731                 else {
732                         /* Allow hibernation, after saving the state: */
733                         modest_osso_save_state();
734                         hildon_program_set_can_hibernate (app, TRUE);
735                 }
736         }
737         
738 }
739
740 static void
741 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
742 {
743         GtkWidget *folder_win = (GtkWidget *) user_data;
744         ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
745         
746         priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
747         wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
748 /*      wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET(priv->header_view)); */
749
750         gtk_widget_show (GTK_WIDGET (priv->folder_view));
751
752         /* Connect signals */
753         connect_signals ((ModestMainWindow*)self);
754
755         /* Set account store */
756         tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
757                                                   TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
758
759         /* Load previous osso state, for instance if we are being restored from 
760          * hibernation:  */
761         modest_osso_load_state ();
762
763         /* Restore window & widget settings */
764         
765         restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
766
767         /* Check if accounts exist and show the account wizard if not */
768         gboolean accounts_exist = 
769                 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
770
771         if (!accounts_exist) {
772                 /* This is necessary to have the main window shown behind the dialog 
773                 It's an ugly hack... jschmid */
774                 gtk_widget_show_all(GTK_WIDGET(self));
775                 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
776         } else {
777                 GSList *accounts;
778                 GtkAction *send_receive_all;
779                 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
780                 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
781                 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager, 
782                                                               "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
783                 gtk_action_set_visible (send_receive_all, g_slist_length (accounts));
784                 modest_account_mgr_free_account_names (accounts);
785         }
786
787
788 }
789
790 ModestWindow *
791 modest_main_window_new (void)
792 {
793         ModestMainWindow *self = NULL;  
794         ModestMainWindowPrivate *priv = NULL;
795         ModestWindowPrivate *parent_priv = NULL;
796         GtkWidget *folder_win = NULL;
797         ModestDimmingRulesGroup *menu_rules_group = NULL;
798         ModestDimmingRulesGroup *toolbar_rules_group = NULL;
799         GtkActionGroup *action_group = NULL;
800         GError *error = NULL;
801         ModestConf *conf = NULL;
802         GtkAction *action = NULL;
803
804         self  = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
805         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
806         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
807
808         parent_priv->ui_manager = gtk_ui_manager_new();
809         parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
810
811         action_group = gtk_action_group_new ("ModestMainWindowActions");
812         gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
813
814         menu_rules_group = modest_dimming_rules_group_new ("ModestMenuDimmingRules", FALSE);
815         toolbar_rules_group = modest_dimming_rules_group_new ("ModestToolbarDimmingRules", TRUE);
816
817         /* Add common actions */
818         gtk_action_group_add_actions (action_group,
819                                       modest_action_entries,
820                                       G_N_ELEMENTS (modest_action_entries),
821                                       self);
822
823         gtk_action_group_add_actions (action_group,
824                                       modest_folder_view_action_entries,
825                                       G_N_ELEMENTS (modest_folder_view_action_entries),
826                                       self);
827
828         gtk_action_group_add_actions (action_group,
829                                       modest_header_view_action_entries,
830                                       G_N_ELEMENTS (modest_header_view_action_entries),
831                                       self);
832
833         gtk_action_group_add_toggle_actions (action_group,
834                                              modest_toggle_action_entries,
835                                              G_N_ELEMENTS (modest_toggle_action_entries),
836                                              self);
837
838         gtk_action_group_add_toggle_actions (action_group,
839                                              modest_main_window_toggle_action_entries,
840                                              G_N_ELEMENTS (modest_main_window_toggle_action_entries),
841                                              self);
842
843         gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
844         g_object_unref (action_group);
845
846         /* Load the UI definition */
847         gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
848                                          MODEST_UIDIR "modest-main-window-ui.xml", &error);
849         if (error != NULL) {
850                 g_warning ("Could not merge modest-ui.xml: %s", error->message);
851                 g_error_free (error);
852                 error = NULL;
853         }
854
855         /* Add common dimming rules */
856         modest_dimming_rules_group_add_rules (menu_rules_group, 
857                                               modest_main_window_menu_dimming_entries,
858                                               G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
859                                               self);
860         modest_dimming_rules_group_add_rules (toolbar_rules_group, 
861                                               modest_main_window_toolbar_dimming_entries,
862                                               G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
863                                               self);
864
865         /* Insert dimming rules group for this window */
866         modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
867         modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
868         g_object_unref (menu_rules_group);
869         g_object_unref (toolbar_rules_group);
870         
871         /* Add accelerators */
872         gtk_window_add_accel_group (GTK_WINDOW (self), 
873                                     gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
874
875         /* Menubar. Update the state of some toggles */
876         parent_priv->menubar = modest_maemo_utils_menubar_to_menu (parent_priv->ui_manager);
877         conf = modest_runtime_get_conf ();
878         action = gtk_ui_manager_get_action (parent_priv->ui_manager, 
879                                             "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
880         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
881                                       modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR, NULL));
882         action = gtk_ui_manager_get_action (parent_priv->ui_manager, 
883                                             "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
884         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
885                                       modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN, NULL));
886         hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
887
888         /* Get device name */
889         modest_maemo_utils_get_device_name ();
890
891         /* header view */
892         priv->header_view =
893                 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
894         if (!priv->header_view)
895                 g_printerr ("modest: cannot instantiate header view\n");
896         modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
897         modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
898                                       MODEST_CONF_HEADER_VIEW_KEY);
899
900         /* Other style properties of header view */
901         g_object_set (G_OBJECT (priv->header_view), 
902                       "rules-hint", FALSE,
903                       NULL);
904
905         /* Empty view */ 
906         priv->empty_view = create_empty_view ();
907                  
908         /* Create scrolled windows */
909         folder_win = gtk_scrolled_window_new (NULL, NULL);
910         priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
911         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
912                                         GTK_POLICY_NEVER,
913                                         GTK_POLICY_AUTOMATIC);
914         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
915                                         GTK_POLICY_NEVER,
916                                         GTK_POLICY_AUTOMATIC);
917
918         /* paned */
919         priv->main_paned = gtk_hpaned_new ();
920         gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
921         gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
922         gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
923
924         /* putting it all together... */
925         priv->main_vbox = gtk_vbox_new (FALSE, 6);
926         gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
927
928         gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
929         
930         HildonProgram *app = hildon_program_get_instance ();
931         hildon_program_add_window (app, HILDON_WINDOW (self));
932         
933         g_signal_connect (G_OBJECT(app), "notify::is-topmost",
934                 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
935
936         g_signal_connect (G_OBJECT(self), "show",
937                           G_CALLBACK (modest_main_window_on_show), folder_win);
938                 
939
940         restore_settings (MODEST_MAIN_WINDOW(self), FALSE);
941
942         return MODEST_WINDOW(self);
943 }
944
945 gboolean 
946 modest_main_window_close_all (ModestMainWindow *self)
947 {
948         GtkWidget *note;
949         GtkResponseType response;
950
951         /* Create the confirmation dialog MSG-NOT308 */
952         note = hildon_note_new_confirmation_add_buttons (GTK_WINDOW (self),
953                                                          _("emev_nc_close_windows"),
954                                                          _("mcen_bd_yes"), GTK_RESPONSE_YES,
955                                                          _("mcen_bd_no"), GTK_RESPONSE_NO,
956                                                          NULL);
957
958         response = gtk_dialog_run (GTK_DIALOG (note));
959         gtk_widget_destroy (GTK_WIDGET (note));
960
961         if (response == GTK_RESPONSE_YES)
962                 return TRUE;
963         else
964                 return FALSE;
965 }
966
967
968 void 
969 modest_main_window_set_style (ModestMainWindow *self, 
970                               ModestMainWindowStyle style)
971 {
972         ModestMainWindowPrivate *priv;
973         ModestWindowPrivate *parent_priv;
974         GtkAction *action;
975
976         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
977
978         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
979         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
980
981         /* no change -> nothing to do */
982         if (priv->style == style)
983                 return;
984
985         /* Get toggle button */
986         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarToggleView");
987
988         priv->style = style;
989         switch (style) {
990         case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
991                 /* Remove main paned */
992                 g_object_ref (priv->main_paned);
993                 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
994
995                 /* Reparent the contents widget to the main vbox */
996                 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
997
998                 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
999                 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1000                 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1001
1002                 if (modest_header_view_has_selected_headers (MODEST_HEADER_VIEW (priv->header_view))) {
1003                         TnyList *selection = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (priv->header_view));
1004                         TnyIterator *iterator = tny_list_create_iterator (selection);
1005                         TnyHeader *header;
1006                         tny_iterator_first (iterator);
1007                         header = TNY_HEADER (tny_iterator_get_current (iterator));
1008                         if (tny_header_get_subject (header))
1009                                 gtk_window_set_title (GTK_WINDOW(self), tny_header_get_subject (header));
1010                         else
1011                                 gtk_window_set_title (GTK_WINDOW (self), _("mail_va_no_subject"));
1012                         g_object_unref (header);
1013                         g_object_unref (iterator);
1014                         g_object_unref (selection);
1015                 }
1016
1017                 break;
1018         case MODEST_MAIN_WINDOW_STYLE_SPLIT:
1019                 /* Remove header view */
1020                 g_object_ref (priv->contents_widget);
1021                 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
1022
1023                 /* Reparent the main paned */
1024                 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
1025                 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1026
1027                 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1028                 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
1029                 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1030
1031                 break;
1032         default:
1033                 g_return_if_reached ();
1034         }
1035
1036         /* Let header view grab the focus if it's being shown */
1037         if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1038                 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1039         else 
1040                 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1041
1042         /* Show changes */
1043         gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1044 }
1045
1046 ModestMainWindowStyle
1047 modest_main_window_get_style (ModestMainWindow *self)
1048 {
1049         ModestMainWindowPrivate *priv;
1050
1051         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1052
1053         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1054         return priv->style;
1055 }
1056
1057
1058
1059 static gboolean
1060 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1061 {
1062         if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1063                 ModestWindowPrivate *parent_priv;
1064                 ModestWindowMgr *mgr;
1065                 gboolean is_fullscreen;
1066                 GtkAction *fs_toggle_action;
1067                 gboolean active;
1068                 
1069                 mgr = modest_runtime_get_window_mgr ();
1070                 
1071                 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1072
1073                 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1074                 
1075                 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1076                 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1077                 if (is_fullscreen != active) {
1078                         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1079                 }
1080         }
1081
1082         return FALSE;
1083
1084 }
1085
1086 static void
1087 set_homogeneous (GtkWidget *widget,
1088                  gpointer data)
1089 {
1090         gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
1091         gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
1092 }
1093
1094 static void 
1095 modest_main_window_show_toolbar (ModestWindow *self,
1096                                  gboolean show_toolbar)
1097 {
1098         ModestMainWindowPrivate *priv = NULL;
1099         ModestWindowPrivate *parent_priv = NULL;        
1100         GtkWidget *reply_button = NULL, *menu = NULL;
1101         GtkWidget *placeholder = NULL;
1102         gint insert_index;
1103
1104         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1105         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1106         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1107
1108         /* Set optimized view status */
1109         priv->optimized_view = !show_toolbar;
1110
1111         if (!parent_priv->toolbar) {
1112                 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
1113                                                                   "/ToolBar");
1114
1115                 /* Set homogeneous toolbar */
1116                 gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar), 
1117                                        set_homogeneous, NULL);
1118         
1119                 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1120                 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1121                 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1122                 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1123                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1124                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1125                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1126                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1127
1128                 /* Add ProgressBar (Transfer toolbar) */ 
1129                 priv->progress_bar = modest_progress_bar_widget_new ();
1130                 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1131                 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1132                 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1133                 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1134                 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1135                 
1136                 /* Connect cancel 'clicked' signal to abort progress mode */
1137                 g_signal_connect(priv->cancel_toolitem, "clicked",
1138                                  G_CALLBACK(cancel_progressbar),
1139                                  self);
1140                 
1141                 /* Add it to the observers list */
1142                 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1143
1144                 /* Add to window */
1145                 hildon_window_add_toolbar (HILDON_WINDOW (self), 
1146                                            GTK_TOOLBAR (parent_priv->toolbar));
1147
1148                 /* Set reply button tap and hold menu */
1149                 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
1150                                                           "/ToolBar/ToolbarMessageReply");
1151                 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1152                                                   "/ToolbarReplyCSM");
1153                 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1154
1155                 /* Set send & receive button tap and hold menu */
1156                 on_account_update (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
1157                                    NULL, self);
1158         }
1159
1160         if (show_toolbar) {
1161                 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */ 
1162                 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1163                 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1164
1165                 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1166                 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1167         } else
1168                 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1169
1170 }
1171
1172 static gint
1173 compare_display_names (ModestAccountData *a,
1174                        ModestAccountData *b)
1175 {
1176         return strcmp (a->display_name, b->display_name);
1177 }
1178
1179 static void 
1180 on_account_update (TnyAccountStore *account_store, 
1181                    const gchar *account_name,
1182                    gpointer user_data)
1183 {
1184         GSList *account_names, *iter, *accounts;
1185         ModestMainWindow *self;
1186         ModestMainWindowPrivate *priv;
1187         ModestWindowPrivate *parent_priv;
1188         ModestAccountMgr *mgr;
1189         gint i, num_accounts;                                   
1190         GtkActionGroup *action_group;
1191         GList *groups;
1192         gchar *default_account;
1193         GtkWidget *send_receive_button, *item;
1194         GtkAction *send_receive_all = NULL;
1195                 
1196         self = MODEST_MAIN_WINDOW (user_data);
1197         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
1198         parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1199
1200         /* Get enabled account IDs */
1201         mgr = modest_runtime_get_account_mgr ();
1202         account_names = modest_account_mgr_account_names (mgr, TRUE);
1203         iter = account_names;
1204         accounts = NULL;
1205
1206         while (iter) {
1207                 ModestAccountData *account_data = 
1208                         modest_account_mgr_get_account_data (mgr, (gchar*) iter->data);
1209                 accounts = g_slist_prepend (accounts, account_data);
1210
1211                 iter = iter->next;
1212         }
1213         modest_account_mgr_free_account_names (account_names);
1214         account_names = NULL;
1215
1216         /* Order the list of accounts by its display name */
1217         accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
1218         num_accounts = g_slist_length (accounts);
1219
1220         send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager, 
1221                                                       "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1222         gtk_action_set_visible (send_receive_all, num_accounts > 1);
1223
1224         /* Delete old send&receive popup items. We can not just do a
1225            menu_detach because it does not work well with
1226            tap_and_hold */
1227         if (priv->accounts_popup)
1228                 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup), 
1229                                        (GtkCallback) gtk_widget_destroy, NULL);
1230
1231         /* Delete old entries in the View menu. Do not free groups, it
1232            belongs to Gtk+ */
1233         groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
1234         while (groups) {
1235                 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
1236                              gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
1237                         gtk_ui_manager_remove_action_group (parent_priv->ui_manager, 
1238                                                             GTK_ACTION_GROUP (groups->data));
1239                         groups = NULL;
1240                         /* Remove uis */
1241                         if (priv->merge_ids) {
1242                                 for (i = 0; i < priv->merge_ids->len; i++)
1243                                         gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
1244                                 g_byte_array_free (priv->merge_ids, TRUE);
1245                         }
1246                         /* We need to call this in order to ensure
1247                            that the new actions are added in the right
1248                            order (alphabetical */
1249                         gtk_ui_manager_ensure_update (parent_priv->ui_manager);
1250                 } else 
1251                         groups = g_list_next (groups);
1252         }
1253         priv->merge_ids = g_byte_array_sized_new (num_accounts);
1254
1255         /* Get send receive button */
1256         send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1257                                                           "/ToolBar/ToolbarSendReceive");
1258
1259         /* Create the menu */
1260         if (num_accounts > 1) {
1261                 if (!priv->accounts_popup)
1262                         priv->accounts_popup = gtk_menu_new ();
1263                 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
1264                 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1265                 g_signal_connect (G_OBJECT (item), 
1266                                   "activate", 
1267                                   G_CALLBACK (on_send_receive_csm_activated),
1268                                   NULL);
1269                 item = gtk_separator_menu_item_new ();
1270                 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1271         }
1272
1273         /* Create a new action group */
1274         default_account = modest_account_mgr_get_default_account (mgr);
1275         action_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
1276         for (i = 0; i < num_accounts; i++) {
1277                 gchar *display_name = NULL;
1278                 
1279                 ModestAccountData *account_data = (ModestAccountData *) g_slist_nth_data (accounts, i);
1280
1281                 /* Create display name. The default account is shown differently */
1282                 if (default_account && account_data->account_name && 
1283                         !(strcmp (default_account, account_data->account_name) == 0)) {
1284                         display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"), 
1285                                                         account_data->display_name);
1286                 }
1287                 else {
1288                         display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"), 
1289                                                         account_data->display_name);
1290                 }
1291
1292                 /* Create action and add it to the action group. The
1293                    action name must be the account name, this way we
1294                    could know in the handlers the account to show */
1295                 if(account_data->account_name) {
1296                         gchar* item_name, *refresh_action_name;
1297                         guint8 merge_id;
1298                         GtkAction *view_account_action, *refresh_account_action;
1299
1300                         view_account_action = gtk_action_new (account_data->account_name,
1301                                                               display_name, NULL, NULL);
1302                         gtk_action_group_add_action (action_group, view_account_action);
1303
1304                         /* Add ui from account data. We allow 2^9-1 account
1305                            changes in a single execution because we're
1306                            downcasting the guint to a guint8 in order to use a
1307                            GByteArray, it should be enough */
1308                         item_name = g_strconcat (account_data->account_name, "Menu", NULL);
1309                         merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
1310                         priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
1311                         gtk_ui_manager_add_ui (parent_priv->ui_manager,
1312                                                merge_id,
1313                                                "/MenuBar/ViewMenu/ViewMenuAdditions",
1314                                                item_name,
1315                                                account_data->account_name,
1316                                                GTK_UI_MANAGER_MENUITEM,
1317                                                FALSE);
1318         
1319                         /* Connect the action signal "activate" */
1320                         g_signal_connect (G_OBJECT (view_account_action),
1321                                           "activate",
1322                                           G_CALLBACK (on_show_account_action_activated),
1323                                           self);
1324
1325                         /* Create the items for the Tools->Send&Receive submenu */
1326                         refresh_action_name = g_strconcat ("SendReceive", account_data->account_name, NULL);
1327                         refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name, 
1328                                                                  display_name, NULL, NULL);
1329                         gtk_action_group_add_action (action_group, refresh_account_action);
1330
1331                         merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
1332                         priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
1333                         gtk_ui_manager_add_ui (parent_priv->ui_manager, 
1334                                                merge_id,
1335                                                "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
1336                                                item_name,
1337                                                refresh_action_name,
1338                                                GTK_UI_MANAGER_MENUITEM,
1339                                                FALSE);
1340                         g_free (refresh_action_name);
1341
1342                         g_signal_connect_data (G_OBJECT (refresh_account_action), 
1343                                                "activate", 
1344                                                G_CALLBACK (on_refresh_account_action_activated), 
1345                                                g_strdup (account_data->account_name),
1346                                                (GClosureNotify) g_free,
1347                                                0);
1348
1349                         /* Create item and add it to the send&receive
1350                            CSM. If there is only one account then
1351                            it'll be no menu */
1352                         if (priv->accounts_popup) {
1353                                 item = gtk_menu_item_new_with_label (display_name);
1354                                 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1355                                 g_signal_connect_data (G_OBJECT (item), 
1356                                                        "activate", 
1357                                                        G_CALLBACK (on_send_receive_csm_activated),
1358                                                        g_strdup (account_data->account_name),
1359                                                        (GClosureNotify) g_free,
1360                                                        0);
1361                         }
1362                         g_free (item_name);
1363                 }
1364
1365                 /* Frees */
1366                 g_free (display_name);
1367                 modest_account_mgr_free_account_data (mgr, account_data);
1368         }
1369         gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 1);
1370
1371         if (priv->accounts_popup) {
1372                 /* Mandatory in order to view the menu contents */
1373                 gtk_widget_show_all (priv->accounts_popup);
1374
1375                 /* Setup tap_and_hold just if was not done before*/
1376                 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
1377                         gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
1378         }
1379
1380         /* Frees */
1381         g_slist_free (accounts);
1382         g_free (default_account);
1383 }
1384
1385 /* 
1386  * This function manages the key events used to navigate between
1387  * header and folder views (when the window is in split view)
1388  *
1389  * FROM         KEY        ACTION
1390  * -------------------------------------------------
1391  * HeaderView   GDK_Left   Move focus to folder view
1392  * FolderView   GDK_Right  Move focus to header view
1393  *
1394  * There is no need to scroll to selected row, the widgets will be the
1395  * responsibles of doing that (probably managing the focus-in event
1396  */
1397 static gboolean 
1398 on_inner_widgets_key_pressed (GtkWidget *widget,
1399                               GdkEventKey *event,
1400                               gpointer user_data)
1401 {
1402         ModestMainWindowPrivate *priv;
1403
1404         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1405
1406         /* Do nothing if we're in SIMPLE style */
1407         if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1408                 return FALSE;
1409
1410         if (MODEST_IS_HEADER_VIEW (widget) && event->keyval == GDK_Left)
1411                 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1412         else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1413                 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1414
1415         return FALSE;
1416 }
1417
1418 static void
1419 set_alignment (GtkWidget *widget,
1420                gpointer data)
1421 {
1422         gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1423         gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1424 }
1425
1426 static GtkWidget *
1427 create_empty_view (void)
1428 {
1429         GtkLabel *label = NULL;
1430         GtkWidget *align = NULL;
1431
1432         align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1433         label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1434         gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);      
1435         gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1436
1437         return GTK_WIDGET(align);
1438 }
1439
1440 static GtkWidget *
1441 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1442 {
1443         /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1444         
1445         GtkWidget *vbox;
1446         GtkWidget *label_w;
1447         gchar *label;
1448         gchar *gray_color_markup;
1449
1450         vbox = gtk_vbox_new (FALSE, 0);
1451
1452         /* Obtain the secondary text color. We need a realized widget, that's why 
1453            we get styled_widget from outside */
1454 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1455         GdkColor color;
1456         gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color);
1457         gray_color_markup = modest_text_utils_get_color_string (&color);
1458 #else
1459         // gray_color_markup is freed below
1460         gray_color_markup = g_strdup ("#BBBBBB");
1461 #endif  
1462         /* Account description: */
1463         
1464         if (modest_tny_account_is_virtual_local_folders (account)
1465                 || (modest_tny_account_is_memory_card_account (account))) {
1466                 gchar *tmp;
1467                 /* Local folders: */
1468         
1469                 /* Get device name */
1470                 gchar *device_name = NULL;
1471                 if (modest_tny_account_is_virtual_local_folders (account))
1472                         device_name = modest_conf_get_string (modest_runtime_get_conf(),
1473                                                       MODEST_CONF_DEVICE_NAME, NULL);
1474                 else
1475                         device_name = g_strdup (tny_account_get_name (account));
1476                                                       
1477                 tmp = g_strdup_printf (_("mcen_fi_localroot_description"), ""); //TODO: Why the ""?
1478                 label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s",
1479                                                  gray_color_markup, tmp, device_name);
1480                 g_free (tmp);
1481                 label_w = gtk_label_new (NULL);
1482                 gtk_label_set_markup (GTK_LABEL (label_w), label);
1483                 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1484                 g_free (device_name);
1485                 g_free (label);
1486         } else {
1487                 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1488                         gtk_box_pack_start (GTK_BOX (vbox), 
1489                                 gtk_label_new (tny_account_get_name (account)), 
1490                                 FALSE, FALSE, 0);
1491                 } else {
1492                         /* Other accounts, such as IMAP and POP: */
1493                         
1494                         GString *proto;
1495                         gchar *tmp;
1496         
1497                         /* Put proto in uppercase */
1498                         proto = g_string_new (tny_account_get_proto (account));
1499                         proto = g_string_ascii_up (proto);
1500                         
1501                         /* note: mcen_fi_localroot_description is something like "%s account"
1502                          * however, we should display "%s account: %s"... therefore, ugly tmp */
1503                         tmp   = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1504                         label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s", 
1505                                                          gray_color_markup, tmp, tny_account_get_name (account));
1506                         g_free (tmp);
1507
1508                         label_w = gtk_label_new (NULL);
1509                         gtk_label_set_markup (GTK_LABEL (label_w), label);
1510                         gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1511                         g_string_free (proto, TRUE);
1512                         g_free (label);
1513                 }
1514         }
1515
1516         /* Message count */
1517         TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1518         label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d", 
1519                                          gray_color_markup, _("mcen_fi_rootfolder_messages"), 
1520                                          modest_tny_folder_store_get_message_count (folder_store));
1521         label_w = gtk_label_new (NULL);
1522         gtk_label_set_markup (GTK_LABEL (label_w), label);
1523         gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1524         g_free (label);
1525
1526         /* Folder count */
1527         label = g_markup_printf_escaped ("<span color='%s'>%s</span>: %d", 
1528                                          gray_color_markup, 
1529                                          _("mcen_fi_rootfolder_folders"), 
1530                                          modest_tny_folder_store_get_folder_count (folder_store));
1531         label_w = gtk_label_new (NULL);
1532         gtk_label_set_markup (GTK_LABEL (label_w), label);
1533         gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1534         g_free (label);
1535
1536         /* Size / Date */
1537         if (modest_tny_account_is_virtual_local_folders (account)
1538                 || modest_tny_account_is_memory_card_account (account)) {
1539
1540                 gchar *size = modest_text_utils_get_display_size (
1541                         modest_tny_folder_store_get_local_size (folder_store));
1542                 
1543                 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s", 
1544                                                  gray_color_markup, _("mcen_fi_rootfolder_size"),
1545                                                  size);
1546                 g_free (size);
1547                 
1548                 label_w = gtk_label_new (NULL);
1549                 gtk_label_set_markup (GTK_LABEL (label_w), label);
1550                 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1551                 g_free (label);
1552         } else if (TNY_IS_ACCOUNT(folder_store)) {
1553                 TnyAccount *account = TNY_ACCOUNT(folder_store);
1554                 
1555                 time_t last_updated;
1556                 gchar *last_updated_string;
1557                 /* Get last updated from configuration */
1558                 last_updated = modest_account_mgr_get_int (modest_runtime_get_account_mgr (), 
1559                                                           tny_account_get_id (account), 
1560                                                           MODEST_ACCOUNT_LAST_UPDATED, 
1561                                                           TRUE);
1562                 if (last_updated > 0) 
1563                         last_updated_string = modest_text_utils_get_display_date(last_updated);
1564                 else
1565                         last_updated_string = g_strdup (_("mcen_va_never"));
1566
1567                 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s", 
1568                                                  gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1569                 label_w = gtk_label_new (NULL);
1570                 gtk_label_set_markup (GTK_LABEL (label_w), label);
1571                 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1572                 g_free (last_updated_string);
1573                 g_free (label);
1574         }
1575
1576         g_free (gray_color_markup);
1577
1578         /* Set alignment */
1579         gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1580
1581         return vbox;
1582 }
1583
1584 gboolean
1585 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1586 {
1587         ModestMainWindowPrivate *priv = NULL;
1588         
1589         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1590
1591         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1592
1593         return priv->send_receive_in_progress;
1594 }
1595
1596 void 
1597 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1598 {
1599         GtkAction *action = NULL;
1600         GtkWidget *widget = NULL;
1601         ModestMainWindowPrivate *priv = NULL;
1602                 
1603         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1604         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1605         
1606         priv->send_receive_in_progress  = TRUE;
1607
1608         action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu"); 
1609         gtk_action_set_sensitive (action, FALSE);
1610 /*         action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1611 /*      gtk_action_set_sensitive (action, FALSE); */
1612         widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");       
1613         gtk_widget_set_sensitive (widget, FALSE);
1614
1615
1616 void 
1617 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1618 {
1619         GtkAction *action = NULL;
1620         GtkWidget *widget = NULL;
1621         ModestMainWindowPrivate *priv = NULL;
1622                 
1623         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1624         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1625
1626         priv->send_receive_in_progress  = FALSE;
1627
1628         action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu"); 
1629         gtk_action_set_sensitive (action, TRUE);
1630 /*         action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu");     */
1631 /*      gtk_action_set_sensitive (action, TRUE); */
1632         widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");       
1633         gtk_widget_set_sensitive (widget, TRUE);
1634
1635
1636
1637 static void
1638 _on_msg_count_changed (ModestHeaderView *header_view,
1639                        TnyFolder *folder,
1640                        TnyFolderChange *change,
1641                        ModestMainWindow *main_window)
1642 {
1643         printf ("DEBUG: %s\n", __FUNCTION__);
1644         gboolean folder_empty = FALSE;
1645         TnyFolderChangeChanged changed;
1646         
1647         g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1648         g_return_if_fail (TNY_IS_FOLDER(folder));
1649         g_return_if_fail (TNY_IS_FOLDER_CHANGE(change));
1650         
1651         changed = tny_folder_change_get_changed (change);
1652         
1653         /* If something changes */
1654         if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1655                 folder_empty = (tny_folder_change_get_new_all_count (change) == 0);     
1656         else
1657                 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1658         
1659         printf ("DEBUG: %s: folder_empty=%d\n", __FUNCTION__, folder_empty);
1660
1661         /* Set contents style of headers view */
1662         if (folder_empty)  {
1663                 modest_main_window_set_contents_style (main_window,
1664                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1665         }
1666         else {
1667                 modest_main_window_set_contents_style (main_window,
1668                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1669         }       
1670 }
1671
1672 void 
1673 modest_main_window_set_contents_style (ModestMainWindow *self, 
1674                                        ModestMainWindowContentsStyle style)
1675 {
1676         ModestMainWindowPrivate *priv;
1677
1678         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1679
1680         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1681
1682         /* We allow to set the same content style than the previously
1683            set if there are details, because it could happen when we're
1684            selecting different accounts consecutively */
1685         if ((priv->contents_style == style) &&
1686             (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1687                 return;
1688
1689         /* Remove previous child. Delete it if it was an account
1690            details widget */
1691         GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1692         if (content) {
1693                 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1694                         g_object_ref (content);
1695                 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1696                         g_object_ref (priv->empty_view);
1697                         gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
1698                 }
1699                 
1700                 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1701         }
1702
1703         priv->contents_style = style;
1704
1705         switch (priv->contents_style) {
1706         case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1707                 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1708                 break;
1709         case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1710         {
1711                 TnyFolderStore *selected_folderstore = 
1712                         modest_folder_view_get_selected (priv->folder_view);
1713                 if (TNY_IS_ACCOUNT (selected_folderstore)) {    
1714                   priv->details_widget = create_details_widget (GTK_WIDGET (self),
1715                                                                 TNY_ACCOUNT (selected_folderstore));
1716
1717                         wrap_in_scrolled_window (priv->contents_widget, 
1718                                          priv->details_widget);
1719                 }
1720                 g_object_unref (selected_folderstore);
1721                 break;
1722         }
1723         case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
1724                 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
1725                 break;
1726         default:
1727                 g_return_if_reached ();
1728         }
1729
1730         /* Show */
1731         gtk_widget_show_all (priv->contents_widget);
1732 }
1733
1734 ModestMainWindowContentsStyle
1735 modest_main_window_get_contents_style (ModestMainWindow *self)
1736 {
1737         ModestMainWindowPrivate *priv;
1738
1739         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1740
1741         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1742         return priv->contents_style;
1743 }
1744
1745
1746 static void 
1747 on_configuration_key_changed (ModestConf* conf, 
1748                               const gchar *key, 
1749                               ModestConfEvent event, 
1750                               ModestMainWindow *self)
1751 {
1752         ModestMainWindowPrivate *priv;
1753         TnyAccount *account;
1754
1755         if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
1756                 return;
1757
1758         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1759
1760         if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1761                 return;
1762
1763         account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
1764         if (TNY_IS_ACCOUNT (account) &&
1765             !strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1766                 GList *children;
1767                 GtkLabel *label;
1768                 const gchar *device_name;
1769                 gchar *new_text;
1770                 
1771                 /* Get label */
1772                 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
1773                 label = GTK_LABEL (children->data);
1774                 
1775                 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1776                                                       MODEST_CONF_DEVICE_NAME, NULL);
1777                 
1778                 new_text = g_strdup_printf ("%s: %s",
1779                                             _("mcen_fi_localroot_description"),
1780                                             device_name);
1781                 
1782                 gtk_label_set_text (label, new_text);
1783                 gtk_widget_show (GTK_WIDGET (label));
1784                 
1785                 g_free (new_text);
1786                 g_list_free (children);
1787         }
1788         g_object_unref (account);
1789 }
1790
1791 static gboolean
1792 set_toolbar_transfer_mode (ModestMainWindow *self)
1793 {
1794         ModestMainWindowPrivate *priv = NULL;
1795         
1796         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1797
1798         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1799
1800         set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
1801         
1802         if (priv->progress_bar_timeout > 0) {
1803                 g_source_remove (priv->progress_bar_timeout);
1804                 priv->progress_bar_timeout = 0;
1805         }
1806
1807         return FALSE;
1808 }
1809
1810 static void 
1811 set_toolbar_mode (ModestMainWindow *self, 
1812                   ModestToolBarModes mode)
1813 {
1814         ModestWindowPrivate *parent_priv = NULL;
1815         ModestMainWindowPrivate *priv = NULL;
1816         GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
1817         
1818         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1819
1820         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1821         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1822
1823         /* In case this was called before the toolbar exists: */
1824         if (!(parent_priv->toolbar))
1825                 return;
1826
1827         g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar)); 
1828         
1829         sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1830         refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1831         cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1832
1833         /* Sets current toolbar mode */
1834         priv->current_toolbar_mode = mode;
1835
1836         /* Show and hide toolbar items */
1837         switch (mode) {
1838         case TOOLBAR_MODE_NORMAL:
1839                 if (sort_action)
1840                         gtk_action_set_visible (sort_action, TRUE);
1841                 if (refresh_action)
1842                         gtk_action_set_visible (refresh_action, TRUE);
1843                 if (priv->progress_toolitem) {
1844                         gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1845                         gtk_widget_hide (priv->progress_toolitem);
1846                 }
1847                 if (priv->progress_bar)
1848                         gtk_widget_hide (priv->progress_bar);
1849                 
1850                 if (cancel_action)
1851                         gtk_action_set_visible (cancel_action, FALSE);
1852 /*              if (priv->sort_toolitem) */
1853 /*                      gtk_widget_show (priv->sort_toolitem); */
1854                 
1855 /*              if (priv->refresh_toolitem) */
1856 /*                      gtk_widget_show (priv->refresh_toolitem); */
1857                         
1858 /*              if (priv->progress_toolitem) */
1859 /*                      gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE); */
1860 /*              if (priv->progress_bar) */
1861 /*                      gtk_widget_hide (priv->progress_bar); */
1862                         
1863 /*              if (priv->cancel_toolitem) */
1864 /*                      gtk_widget_hide (priv->cancel_toolitem); */
1865
1866                 /* Hide toolbar if optimized view is enabled */
1867                 if (priv->optimized_view)
1868                         gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
1869                 break;
1870         case TOOLBAR_MODE_TRANSFER:
1871                 if (sort_action)
1872                         gtk_action_set_visible (sort_action, FALSE);
1873                 if (refresh_action)
1874                         gtk_action_set_visible (refresh_action, FALSE);
1875                 if (cancel_action)
1876                         gtk_action_set_visible (cancel_action, TRUE);
1877                 if (priv->progress_toolitem) {
1878                         gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1879                         gtk_widget_show (priv->progress_toolitem);
1880                 }
1881                 if (priv->progress_bar)
1882                         gtk_widget_show (priv->progress_bar);
1883
1884 /*              if (priv->sort_toolitem) */
1885 /*                      gtk_widget_hide (priv->sort_toolitem); */
1886                 
1887 /*              if (priv->refresh_toolitem) */
1888 /*                      gtk_widget_hide (priv->refresh_toolitem); */
1889                 
1890 /*              if (priv->progress_toolitem) */
1891 /*                      gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE); */
1892 /*              if (priv->progress_bar) */
1893 /*                      gtk_widget_show (priv->progress_bar); */
1894                         
1895 /*              if (priv->cancel_toolitem) */
1896 /*                      gtk_widget_show (priv->cancel_toolitem); */
1897
1898                 /* Show toolbar if it's hiden (optimized view ) */
1899                 if (priv->optimized_view)
1900                         gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1901                 break;
1902         default:
1903                 g_return_if_reached ();
1904         }
1905 }
1906
1907 static void
1908 cancel_progressbar (GtkToolButton *toolbutton,
1909                     ModestMainWindow *self)
1910 {
1911         GSList *tmp;
1912         ModestMainWindowPrivate *priv;
1913         
1914         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1915
1916         /* Get operation observers and cancel its current operation */
1917         tmp = priv->progress_widgets;
1918         while (tmp) {
1919                 modest_progress_object_cancel_current_operation (MODEST_PROGRESS_OBJECT(tmp->data));
1920                 tmp=g_slist_next(tmp);
1921         }
1922 }
1923
1924 static gboolean
1925 observers_empty (ModestMainWindow *self)
1926 {
1927         GSList *tmp = NULL;
1928         ModestMainWindowPrivate *priv;
1929         gboolean is_empty = TRUE;
1930         guint pending_ops = 0;
1931  
1932         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1933         tmp = priv->progress_widgets;
1934
1935         /* Check all observers */
1936         while (tmp && is_empty)  {
1937                 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
1938                 is_empty = pending_ops == 0;
1939                 
1940                 tmp = g_slist_next(tmp);
1941         }
1942         
1943         return is_empty;
1944 }
1945
1946 static void
1947 on_queue_changed (ModestMailOperationQueue *queue,
1948                   ModestMailOperation *mail_op,
1949                   ModestMailOperationQueueNotification type,
1950                   ModestMainWindow *self)
1951 {
1952         ModestMainWindowPrivate *priv;
1953         ModestMailOperationTypeOperation op_type;
1954         ModestToolBarModes mode;
1955         GSList *tmp;
1956         gboolean mode_changed = FALSE;
1957 /*      ModestMailOperationStatus status; */
1958
1959         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1960         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1961                
1962         /* Get toolbar mode from operation id*/
1963         op_type = modest_mail_operation_get_type_operation (mail_op);
1964         switch (op_type) {
1965         case MODEST_MAIL_OPERATION_TYPE_SEND:
1966         case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
1967         case MODEST_MAIL_OPERATION_TYPE_OPEN:
1968                 mode = TOOLBAR_MODE_TRANSFER;
1969                 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
1970                         mode_changed = TRUE;
1971                 break;
1972         default:
1973                 mode = TOOLBAR_MODE_NORMAL;
1974                 
1975         }
1976                 
1977                        
1978         /* Add operation observers and change toolbar if neccessary*/
1979         tmp = priv->progress_widgets;
1980         switch (type) {
1981         case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
1982                 if (mode == TOOLBAR_MODE_TRANSFER) {
1983                         if (mode_changed)
1984                                 set_toolbar_transfer_mode(self);                    
1985                         while (tmp) {
1986                                 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1987                                                                       mail_op);
1988                                 tmp = g_slist_next (tmp);
1989                         }
1990                 }
1991                 break;
1992         case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED:
1993                 /* Change toolbar mode */
1994                 if (mode == TOOLBAR_MODE_TRANSFER) {                    
1995                         while (tmp) {
1996                                 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1997                                                                          mail_op);
1998                                 tmp = g_slist_next (tmp);
1999                         }
2000                         
2001                         /* If no more operations are being observed, NORMAL mode is enabled again */
2002                         if (observers_empty (self)) {
2003                                 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
2004                                 
2005                         }
2006                 }
2007
2008                 break;
2009         }       
2010
2011 }
2012
2013 static void 
2014 on_show_account_action_activated  (GtkAction *action,
2015                                    gpointer user_data)
2016 {
2017         ModestAccountData *acc_data;
2018         ModestMainWindow *self;
2019         ModestMainWindowPrivate *priv;
2020         ModestAccountMgr *mgr;
2021         const gchar *acc_name;
2022
2023         self = MODEST_MAIN_WINDOW (user_data);
2024         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2025
2026         /* Get account data */
2027         acc_name = gtk_action_get_name (action);
2028         mgr = modest_runtime_get_account_mgr ();
2029         acc_data = modest_account_mgr_get_account_data (mgr, acc_name);
2030
2031         /* Set the new visible & active account */
2032         if (acc_data->store_account) { 
2033                 modest_folder_view_set_account_id_of_visible_server_account (priv->folder_view,
2034                                                                              acc_data->store_account->account_name);
2035                 modest_window_set_active_account (MODEST_WINDOW (self), acc_data->account_name);
2036         }
2037
2038         /* Free */
2039         modest_account_mgr_free_account_data (mgr, acc_data);
2040 }
2041
2042 static void
2043 refresh_account (const gchar *account_name)
2044 {
2045         ModestWindow *win;
2046
2047         win = MODEST_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2048
2049         /* If account_name == NULL, we must update all (option All) */
2050         if (!account_name)
2051                 modest_ui_actions_do_send_receive_all (win);
2052         else
2053                 modest_ui_actions_do_send_receive (account_name, win);
2054         
2055 }
2056
2057 static void 
2058 on_refresh_account_action_activated  (GtkAction *action,
2059                                       gpointer user_data)
2060 {
2061         refresh_account ((const gchar*) user_data);
2062 }
2063
2064 static void
2065 on_send_receive_csm_activated (GtkMenuItem *item,
2066                                gpointer user_data)
2067 {
2068         refresh_account ((const gchar*) user_data);
2069 }
2070
2071 static gboolean
2072 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2073 {
2074         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2075
2076         hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2077         return FALSE;
2078
2079 }
2080
2081 static gboolean
2082 on_folder_view_focus_in (GtkWidget *widget,
2083                          GdkEventFocus *event,
2084                          gpointer userdata)
2085 {
2086         ModestMainWindow *main_window = NULL;
2087         
2088         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2089         main_window = MODEST_MAIN_WINDOW (userdata);
2090         
2091         /* Update toolbar dimming state */
2092         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2093
2094         return FALSE;
2095 }
2096
2097 static gboolean
2098 on_header_view_focus_in (GtkWidget *widget,
2099                          GdkEventFocus *event,
2100                          gpointer userdata)
2101 {
2102         ModestMainWindow *main_window = NULL;
2103         ModestMainWindowPrivate *priv = NULL;
2104
2105         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2106         main_window = MODEST_MAIN_WINDOW (userdata);
2107         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
2108
2109         if (modest_header_view_has_selected_headers (MODEST_HEADER_VIEW (priv->header_view))) {
2110                 TnyList *selection = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (priv->header_view));
2111                 TnyIterator *iterator = tny_list_create_iterator (selection);
2112                 TnyHeader *header;
2113
2114                 tny_iterator_first (iterator);
2115                 header = TNY_HEADER (tny_iterator_get_current (iterator));
2116                 
2117                 if (tny_header_get_subject (header))
2118                         gtk_window_set_title (GTK_WINDOW(main_window), tny_header_get_subject (header));
2119                 else
2120                         gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
2121
2122                 g_object_unref (header);
2123                 g_object_unref (iterator);
2124                 g_object_unref (selection);
2125         }
2126
2127
2128         /* Update toolbar dimming state */
2129         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2130
2131         return FALSE;
2132 }
2133
2134 static void 
2135 modest_main_window_on_folder_selection_changed (ModestFolderView *folder_view,
2136                                                 TnyFolderStore *folder_store, 
2137                                                 gboolean selected,
2138                                                 ModestMainWindow *main_window)
2139 {
2140         ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (main_window);
2141         GtkAction *action = NULL;
2142         gboolean show_reply = TRUE;
2143         gboolean show_forward = TRUE;
2144         gboolean show_cancel_send = FALSE;
2145         gboolean show_clipboard = TRUE;
2146         gboolean show_delete = TRUE;
2147
2148         if (selected) {
2149                 if (TNY_IS_ACCOUNT (folder_store)) {
2150                         show_reply = show_forward = show_cancel_send = show_clipboard = show_delete = FALSE;
2151                 } else if (TNY_IS_FOLDER (folder_store)) {
2152                         if (modest_tny_folder_is_local_folder (TNY_FOLDER (folder_store))) {
2153                                 TnyFolderType folder_type = modest_tny_folder_get_local_folder_type (
2154                                         TNY_FOLDER (folder_store));
2155                                 switch (folder_type) {
2156                                 case TNY_FOLDER_TYPE_DRAFTS:
2157                                         show_clipboard = show_delete = TRUE;
2158                                         show_reply = show_forward = show_cancel_send = FALSE;
2159                                         break;
2160                                 case TNY_FOLDER_TYPE_SENT:
2161                                         show_forward = show_clipboard = show_delete = TRUE;
2162                                         show_reply = show_cancel_send = FALSE;
2163                                         break;
2164                                 case TNY_FOLDER_TYPE_OUTBOX:
2165                                         show_clipboard = show_delete = show_cancel_send = TRUE;
2166                                         show_reply = show_forward = FALSE;
2167                                         break;
2168                                 default:
2169                                         show_reply = show_forward = show_clipboard = show_delete = TRUE;
2170                                         show_cancel_send = FALSE;
2171                                 }
2172                         } else {
2173                                 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2174                                 show_cancel_send = FALSE;
2175                         }
2176                 }
2177         }
2178
2179         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReply");
2180         gtk_action_set_visible (action, show_reply);
2181         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReplyAll");
2182         gtk_action_set_visible (action, show_reply);
2183         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMForward");
2184         gtk_action_set_visible (action, show_forward);
2185         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCancelSending");
2186         gtk_action_set_visible (action, show_cancel_send);
2187         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCut");
2188         gtk_action_set_visible (action, show_clipboard);
2189         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCopy");
2190         gtk_action_set_visible (action, show_clipboard);
2191         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMPaste");
2192         gtk_action_set_visible (action, show_clipboard);
2193         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMDelete");
2194         gtk_action_set_visible (action, show_delete);
2195
2196         /* We finally call to the ui actions handler, after updating properly
2197          * the header view CSM */
2198         modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window);
2199
2200 }
2201
2202 gboolean 
2203 modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window,
2204                                                    GtkTreeModel *model,
2205                                                    GtkTreeRowReference *row_reference,
2206                                                    ModestMainWindow *self)
2207 {
2208         ModestMainWindowPrivate *priv = NULL;
2209         GtkTreeModel *header_model = NULL;
2210         GtkTreePath *path = NULL;
2211
2212         g_return_val_if_fail (MODEST_MSG_VIEW_WINDOW (view_window), FALSE);
2213         g_return_val_if_fail (MODEST_MAIN_WINDOW (self), FALSE);
2214         g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE);
2215
2216         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2217         header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->header_view));
2218
2219         /* Do nothing if we changed the folder in the main view */
2220         if (header_model != model)
2221                 return FALSE;
2222
2223         /* Select the message in the header view */
2224         path = gtk_tree_row_reference_get_path (row_reference);
2225         _modest_header_view_select_from_path (MODEST_HEADER_VIEW (priv->header_view), path);
2226         gtk_tree_path_free (path);
2227
2228         return TRUE;
2229 }