* Review ModestProgressBarWidge, adding a GtkAlignment and
[modest] / src / maemo / modest-main-window.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include <glib/gi18n.h>
31 #include <gtk/gtktreeviewcolumn.h>
32 #include <tny-account-store-view.h>
33 #include <tny-simple-list.h>
34 #include "modest-hildon-includes.h"
35 #include "modest-defs.h"
36 #include <string.h>
37
38 #include "widgets/modest-main-window.h"
39 #include "widgets/modest-msg-edit-window.h"
40 #include "widgets/modest-account-view-window.h"
41 #include "modest-runtime.h"
42 #include "modest-account-mgr-helpers.h"
43 #include "modest-platform.h"
44 #include "modest-widget-memory.h"
45 #include "modest-window-priv.h"
46 #include "modest-main-window-ui.h"
47 #include "modest-account-mgr.h"
48 #include "modest-tny-account.h"
49 #include "modest-conf.h"
50 #include <modest-maemo-utils.h>
51 #include "modest-tny-platform-factory.h"
52 #include "modest-tny-msg.h"
53 #include "modest-mail-operation.h"
54 #include "modest-icon-names.h"
55 #include "modest-progress-bar-widget.h"
56
57 /* 'private'/'protected' functions */
58 static void modest_main_window_class_init    (ModestMainWindowClass *klass);
59 static void modest_main_window_init          (ModestMainWindow *obj);
60 static void modest_main_window_finalize      (GObject *obj);
61 static gboolean modest_main_window_window_state_event (GtkWidget *widget, 
62                                                            GdkEventWindowState *event, 
63                                                            gpointer userdata);
64
65 static void connect_signals (ModestMainWindow *self);
66 static void restore_sizes (ModestMainWindow *self);
67 static void save_sizes (ModestMainWindow *self);
68
69 static void modest_main_window_show_toolbar   (ModestWindow *window,
70                                                gboolean show_toolbar);
71
72 static void cancel_progressbar (GtkToolButton *toolbutton,
73                                 ModestMainWindow *self);
74
75 static void         on_queue_changed                     (ModestMailOperationQueue *queue,
76                                                           ModestMailOperation *mail_op,
77                                                           ModestMailOperationQueueNotification type,
78                                                           ModestMainWindow *self);
79
80 static void on_account_update                 (TnyAccountStore *account_store, 
81                                                gchar *account_name,
82                                                gpointer user_data);
83
84 static gboolean on_inner_widgets_key_pressed  (GtkWidget *widget,
85                                                GdkEventKey *event,
86                                                gpointer user_data);
87
88 static void on_configuration_key_changed      (ModestConf* conf, 
89                                                const gchar *key, 
90                                                ModestConfEvent event, 
91                                                ModestMainWindow *self);
92
93 static void 
94 set_toolbar_mode (ModestMainWindow *self, 
95                   ModestToolBarModes mode);
96
97 /* list my signals */
98 enum {
99         /* MY_SIGNAL_1, */
100         /* MY_SIGNAL_2, */
101         LAST_SIGNAL
102 };
103
104
105 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
106 struct _ModestMainWindowPrivate {
107         GtkWidget *msg_paned;
108         GtkWidget *main_paned;
109         GtkWidget *main_vbox;
110         GtkWidget *contents_widget;
111
112         /* Progress observers */
113         GtkWidget        *progress_bar;
114         GSList           *progress_widgets;
115
116         /* Tollbar items */
117         GtkWidget   *progress_toolitem;
118         GtkWidget   *cancel_toolitem;
119         GtkWidget   *sort_toolitem;
120         GtkWidget   *refresh_toolitem;
121         ModestToolBarModes current_toolbar_mode;
122
123         /* On-demand widgets */
124         GtkWidget *accounts_popup;
125         GtkWidget *details_widget;
126
127
128         ModestHeaderView *header_view;
129         ModestFolderView *folder_view;
130
131         ModestMainWindowStyle style;
132         ModestMainWindowContentsStyle contents_style;
133 };
134 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
135                                                 MODEST_TYPE_MAIN_WINDOW, \
136                                                 ModestMainWindowPrivate))
137
138 typedef struct _GetMsgAsyncHelper {
139         ModestMainWindowPrivate *main_window_private;
140         guint action;
141         ModestTnyMsgReplyType reply_type;
142         ModestTnyMsgForwardType forward_type;
143         gchar *from;
144         TnyIterator *iter;
145 } GetMsgAsyncHelper;
146
147
148 /* globals */
149 static GtkWindowClass *parent_class = NULL;
150
151
152 /* Private actions */
153 static const GtkActionEntry modest_folder_view_action_entries [] = {
154
155         /* Folder View CSM actions */
156         { "FolderViewCSMNewFolder", NULL, N_("FIXME: New Folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
157         { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
158         { "FolderViewCSMPasteMsgs", NULL, N_("FIXME: Paste"), NULL, NULL, NULL },
159         { "FolderViewCSMDeleteFolder", NULL, N_("FIXME: Delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
160         { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, NULL },
161         { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, NULL },
162 };
163
164 /************************************************************************/
165
166 GType
167 modest_main_window_get_type (void)
168 {
169         static GType my_type = 0;
170         if (!my_type) {
171                 static const GTypeInfo my_info = {
172                         sizeof(ModestMainWindowClass),
173                         NULL,           /* base init */
174                         NULL,           /* base finalize */
175                         (GClassInitFunc) modest_main_window_class_init,
176                         NULL,           /* class finalize */
177                         NULL,           /* class data */
178                         sizeof(ModestMainWindow),
179                         1,              /* n_preallocs */
180                         (GInstanceInitFunc) modest_main_window_init,
181                         NULL
182                 };
183                 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
184                                                   "ModestMainWindow",
185                                                   &my_info, 0);
186         }
187         return my_type;
188 }
189
190 static void
191 modest_main_window_class_init (ModestMainWindowClass *klass)
192 {
193         GObjectClass *gobject_class;
194         gobject_class = (GObjectClass*) klass;
195         ModestWindowClass *modest_window_class;
196
197         modest_window_class = (ModestWindowClass *) klass;
198
199         parent_class            = g_type_class_peek_parent (klass);
200         gobject_class->finalize = modest_main_window_finalize;
201
202         modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
203
204         g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
205 }
206
207 static void
208 modest_main_window_init (ModestMainWindow *obj)
209 {
210         ModestMainWindowPrivate *priv;
211
212         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
213
214         priv->msg_paned    = NULL;
215         priv->main_paned   = NULL;      
216         priv->main_vbox    = NULL;
217         priv->header_view  = NULL;
218         priv->folder_view  = NULL;
219         priv->contents_widget  = NULL;
220         priv->accounts_popup  = NULL;
221         priv->details_widget  = NULL;
222
223         priv->progress_widgets  = NULL;
224         priv->progress_bar = NULL;
225         priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
226
227         priv->style  = MODEST_MAIN_WINDOW_STYLE_SPLIT;
228         priv->contents_style  = MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS;
229 }
230
231 static void
232 modest_main_window_finalize (GObject *obj)
233 {
234         ModestMainWindowPrivate *priv;
235
236         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
237
238         g_slist_free (priv->progress_widgets);
239
240         G_OBJECT_CLASS(parent_class)->finalize (obj);
241 }
242
243 GtkWidget*
244 modest_main_window_get_child_widget (ModestMainWindow *self,
245                                      ModestWidgetType widget_type)
246 {
247         ModestMainWindowPrivate *priv;
248         GtkWidget *widget;
249         
250         g_return_val_if_fail (self, NULL);
251         g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_WIDGET_TYPE_NUM,
252                               NULL);
253         
254         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
255
256         switch (widget_type) {
257         case MODEST_WIDGET_TYPE_HEADER_VIEW:
258                 widget = (GtkWidget*)priv->header_view; break;
259         case MODEST_WIDGET_TYPE_FOLDER_VIEW:
260                 widget = (GtkWidget*)priv->folder_view; break;
261         default:
262                 return NULL;
263         }
264
265         return widget ? GTK_WIDGET(widget) : NULL;
266 }
267
268
269
270 static void
271 restore_sizes (ModestMainWindow *self)
272 {
273         ModestConf *conf;
274         ModestMainWindowPrivate *priv;
275
276         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
277
278         conf = modest_runtime_get_conf ();
279         
280         modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
281                                       MODEST_CONF_MAIN_PANED_KEY);
282         modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
283                                       MODEST_CONF_HEADER_VIEW_KEY);
284         modest_widget_memory_restore (conf, G_OBJECT(self), 
285                                       MODEST_CONF_MAIN_WINDOW_KEY);
286 }
287
288
289 static void
290 save_sizes (ModestMainWindow *self)
291 {
292         ModestConf *conf;
293         ModestMainWindowPrivate *priv;
294                 
295         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
296         conf = modest_runtime_get_conf ();
297         
298         modest_widget_memory_save (conf,G_OBJECT(self), 
299                                    MODEST_CONF_MAIN_WINDOW_KEY);
300         modest_widget_memory_save (conf, G_OBJECT(priv->main_paned), 
301                                    MODEST_CONF_MAIN_PANED_KEY);
302         modest_widget_memory_save (conf, G_OBJECT(priv->header_view), 
303                                    MODEST_CONF_HEADER_VIEW_KEY);
304 }
305
306 static void
307 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
308 {
309         if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
310                 gtk_scrolled_window_add_with_viewport
311                         (GTK_SCROLLED_WINDOW(win), widget);
312         else
313                 gtk_container_add (GTK_CONTAINER(win),
314                                    widget);
315 }
316
317
318 static gboolean
319 on_delete_event (GtkWidget *widget, GdkEvent  *event, ModestMainWindow *self)
320 {
321         save_sizes (self);
322         return FALSE;
323 }
324
325
326 static void
327 on_connection_changed (TnyDevice *device, gboolean online, ModestMainWindow *self)
328 {
329         /* When going online, do the equivalent of pressing the send/receive button, 
330          * as per the specification:
331          * (without the check for >0 accounts, though that is not specified): */
332         if (online) {
333                 do_send_receive (MODEST_WINDOW (self));
334         }
335 }
336
337
338
339 static void
340 connect_signals (ModestMainWindow *self)
341 {       
342         ModestWindowPrivate *parent_priv;
343         ModestMainWindowPrivate *priv;
344         GtkWidget *menu;
345         
346         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
347         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
348         
349         /* folder view */
350         g_signal_connect (G_OBJECT(priv->folder_view), "key-press-event",
351                           G_CALLBACK(on_inner_widgets_key_pressed), self);
352         g_signal_connect (G_OBJECT(priv->folder_view), "folder_selection_changed",
353                           G_CALLBACK(modest_ui_actions_on_folder_selection_changed), self);
354         g_signal_connect (G_OBJECT(priv->folder_view), "folder-display-name-changed",
355                           G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
356
357         menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
358         gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
359
360         /* header view */
361 /*      g_signal_connect (G_OBJECT(priv->header_view), "status_update", */
362 /*                        G_CALLBACK(modest_ui_actions_on_header_status_update), self); */
363         g_signal_connect (G_OBJECT(priv->header_view), "header_selected",
364                           G_CALLBACK(modest_ui_actions_on_header_selected), self);
365         g_signal_connect (G_OBJECT(priv->header_view), "header_activated",
366                           G_CALLBACK(modest_ui_actions_on_header_activated), self);
367         g_signal_connect (G_OBJECT(priv->header_view), "item_not_found",
368                           G_CALLBACK(modest_ui_actions_on_item_not_found), self);
369         g_signal_connect (G_OBJECT(priv->header_view), "key-press-event",
370                           G_CALLBACK(on_inner_widgets_key_pressed), self);
371
372         /* window */
373         g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
374         g_signal_connect (G_OBJECT (self), "window-state-event",
375                           G_CALLBACK (modest_main_window_window_state_event),
376                           NULL);
377         g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
378
379         /* Mail Operation Queue */
380         g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
381                           "queue-changed",
382                           G_CALLBACK (on_queue_changed),
383                           self);
384
385         /* Track changes in the device name */
386         g_signal_connect (G_OBJECT(modest_runtime_get_conf ()),
387                           "key_changed",
388                           G_CALLBACK (on_configuration_key_changed), 
389                           self);
390
391         /* Track account changes. We need to refresh the toolbar */
392         g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
393                           "account_update",
394                           G_CALLBACK (on_account_update),
395                           self);
396
397         /* Device */
398         g_signal_connect (G_OBJECT(modest_runtime_get_device()), "connection_changed",
399                           G_CALLBACK(on_connection_changed), self);
400 }
401
402 /** Idle handler, to send/receive at startup .*/
403 gboolean
404 sync_accounts_cb (ModestMainWindow *win)
405 {
406         do_send_receive (MODEST_WINDOW(win));
407         return FALSE; /* Do not call this idle handler again. */
408 }
409
410
411 ModestWindow*
412 modest_main_window_new (void)
413 {
414         ModestMainWindow *self; 
415         ModestMainWindowPrivate *priv;
416         ModestWindowPrivate *parent_priv;
417         GtkWidget *folder_win;
418         GtkActionGroup *action_group;
419         GError *error = NULL;
420         TnyFolderStoreQuery *query;
421         GdkPixbuf *window_icon;
422         ModestConf *conf;
423         GtkAction *action;
424
425         self  = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
426         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
427         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
428
429         parent_priv->ui_manager = gtk_ui_manager_new();
430         action_group = gtk_action_group_new ("ModestMainWindowActions");
431         gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
432
433         /* Add common actions */
434         gtk_action_group_add_actions (action_group,
435                                       modest_action_entries,
436                                       G_N_ELEMENTS (modest_action_entries),
437                                       self);
438
439         gtk_action_group_add_actions (action_group,
440                                       modest_folder_view_action_entries,
441                                       G_N_ELEMENTS (modest_folder_view_action_entries),
442                                       self);
443
444         gtk_action_group_add_toggle_actions (action_group,
445                                              modest_toggle_action_entries,
446                                              G_N_ELEMENTS (modest_toggle_action_entries),
447                                              self);
448
449         gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
450         g_object_unref (action_group);
451
452         /* Load the UI definition */
453         gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
454                                          MODEST_UIDIR "modest-main-window-ui.xml", &error);
455         if (error != NULL) {
456                 g_warning ("Could not merge modest-ui.xml: %s", error->message);
457                 g_error_free (error);
458                 error = NULL;
459         }
460
461         /* Add accelerators */
462         gtk_window_add_accel_group (GTK_WINDOW (self), 
463                                     gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
464
465         /* Menubar. Update the state of some toggles */
466         parent_priv->menubar = modest_maemo_utils_menubar_to_menu (parent_priv->ui_manager);
467         conf = modest_runtime_get_conf ();
468         action = gtk_ui_manager_get_action (parent_priv->ui_manager, 
469                                             "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
470         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
471                                       modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR, NULL));
472         action = gtk_ui_manager_get_action (parent_priv->ui_manager, 
473                                             "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
474         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
475                                       modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN, NULL));
476         hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
477
478         /* folder view */
479         query = tny_folder_store_query_new ();
480         tny_folder_store_query_add_item (query, NULL,
481                                          TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED);
482         priv->folder_view = MODEST_FOLDER_VIEW(modest_folder_view_new (query));
483         if (!priv->folder_view)
484                 g_printerr ("modest: cannot instantiate folder view\n");
485         g_object_unref (G_OBJECT (query));
486         modest_folder_view_set_style (priv->folder_view,
487                                       MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
488
489         /* Get device name */
490         modest_maemo_utils_get_device_name ();
491
492         /* header view */
493         priv->header_view  =
494                 MODEST_HEADER_VIEW(modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
495         if (!priv->header_view)
496                 g_printerr ("modest: cannot instantiate header view\n");
497         modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
498         
499         /* Create scrolled windows */
500         folder_win = gtk_scrolled_window_new (NULL, NULL);
501         priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
502         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
503                                         GTK_POLICY_NEVER,
504                                         GTK_POLICY_AUTOMATIC);
505         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
506                                         GTK_POLICY_NEVER,
507                                         GTK_POLICY_AUTOMATIC);
508
509         wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
510         wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET(priv->header_view));
511
512         /* paned */
513         priv->main_paned = gtk_hpaned_new ();
514         gtk_paned_add1 (GTK_PANED(priv->main_paned), folder_win);
515         gtk_paned_add2 (GTK_PANED(priv->main_paned), priv->contents_widget);
516         gtk_widget_show (GTK_WIDGET(priv->header_view));
517         gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
518
519         /* putting it all together... */
520         priv->main_vbox = gtk_vbox_new (FALSE, 6);
521         gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
522
523         gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
524         restore_sizes (MODEST_MAIN_WINDOW(self));
525
526         /* Set window icon */
527         window_icon = modest_platform_get_icon (MODEST_APP_ICON);
528         gtk_window_set_icon (GTK_WINDOW (self), window_icon);
529         
530         /* Connect signals */
531         connect_signals (self);
532
533         /* Set account store */
534         tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
535                                                   TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
536
537         /* do send & receive when we are idle */
538         g_idle_add ((GSourceFunc)sync_accounts_cb, self);
539         
540         return MODEST_WINDOW(self);
541 }
542
543 gboolean 
544 modest_main_window_close_all (ModestMainWindow *self)
545 {
546         GtkWidget *note;
547         GtkResponseType response;
548
549         /* Create the confirmation dialog MSG-NOT308 */
550         note = hildon_note_new_confirmation_add_buttons (GTK_WINDOW (self),
551                                                          _("emev_nc_close_windows"),
552                                                          _("mcen_bd_yes"), GTK_RESPONSE_YES,
553                                                          _("mcen_bd_no"), GTK_RESPONSE_NO,
554                                                          NULL);
555
556         response = gtk_dialog_run (GTK_DIALOG (note));
557         gtk_widget_destroy (GTK_WIDGET (note));
558
559         if (response == GTK_RESPONSE_YES)
560                 return TRUE;
561         else
562                 return FALSE;
563 }
564
565
566 void 
567 modest_main_window_set_style (ModestMainWindow *self, 
568                               ModestMainWindowStyle style)
569 {
570         ModestMainWindowPrivate *priv;
571
572         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
573
574         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
575
576         /* no change -> nothing to do */
577         if (priv->style == style)
578                 return;
579
580         priv->style = style;
581
582         switch (style) {
583         case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
584                 /* Remove main paned */
585                 g_object_ref (priv->main_paned);
586                 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
587
588                 /* Reparent the contents widget to the main vbox */
589                 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
590
591                 break;
592         case MODEST_MAIN_WINDOW_STYLE_SPLIT:
593                 /* Remove header view */
594                 g_object_ref (priv->contents_widget);
595                 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
596
597                 /* Reparent the main paned */
598                 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
599                 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
600                 break;
601         default:
602                 g_return_if_reached ();
603         }
604
605         /* Let header view grab the focus if it's being shown */
606         if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
607                 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
608         else 
609                 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
610
611         /* Show changes */
612         gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
613 }
614
615 ModestMainWindowStyle
616 modest_main_window_get_style (ModestMainWindow *self)
617 {
618         ModestMainWindowPrivate *priv;
619
620         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
621
622         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
623         return priv->style;
624 }
625
626
627
628 static gboolean
629 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
630 {
631         if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
632                 ModestWindowPrivate *parent_priv;
633                 ModestWindowMgr *mgr;
634                 gboolean is_fullscreen;
635                 GtkAction *fs_toggle_action;
636                 gboolean active;
637                 
638                 mgr = modest_runtime_get_window_mgr ();
639                 
640                 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
641
642                 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
643                 
644                 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
645                 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
646                 if (is_fullscreen != active) {
647                         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
648                 }
649         }
650
651         return FALSE;
652
653 }
654
655 static void
656 set_homogeneous (GtkWidget *widget,
657                  gpointer data)
658 {
659         gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
660         gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
661 }
662
663 static void 
664 modest_main_window_show_toolbar (ModestWindow *self,
665                                  gboolean show_toolbar)
666 {
667         ModestMainWindowPrivate *priv = NULL;
668         ModestWindowPrivate *parent_priv = NULL;        
669         GtkWidget *reply_button = NULL, *menu = NULL;
670         GtkWidget *placeholder = NULL;
671         gint insert_index;
672
673         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
674         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
675
676         if (!parent_priv->toolbar && show_toolbar) {
677                 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
678                                                                   "/ToolBar");
679
680                 /* Set homogeneous toolbar */
681                 gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar), 
682                                        set_homogeneous, NULL);
683         
684                 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
685                 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
686                 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
687                 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
688                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
689                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
690                 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
691                 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
692
693                 /* Add ProgressBar (Transfer toolbar) */ 
694                 priv->progress_bar = modest_progress_bar_widget_new ();
695                 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
696                 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
697                 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
698                 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
699                 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
700                 
701                 /* Connect cancel 'clicked' signal to abort progress mode */
702                 g_signal_connect(priv->cancel_toolitem, "clicked",
703                                  G_CALLBACK(cancel_progressbar),
704                                  self);
705                 
706                 /* Add it to the observers list */
707                 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
708
709                 /* Add to window */
710                 hildon_window_add_toolbar (HILDON_WINDOW (self), 
711                                            GTK_TOOLBAR (parent_priv->toolbar));
712
713                 /* Set reply button tap and hold menu */
714                 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
715                                                           "/ToolBar/ToolbarMessageReply");
716                 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
717                                                   "/ToolbarReplyCSM");
718                 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
719
720                 /* Set send & receive button tap and hold menu */
721                 on_account_update (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
722                                    NULL, self);
723         }
724
725         /* TODO: Why is this sometimes NULL? murrayc */
726         if (parent_priv->toolbar) {
727                 if (show_toolbar) {
728                         gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
729                         set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
730                 } else
731                         gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
732         }
733 }
734
735 /*
736  * TODO: modify the menu dynamically. Add handlers to each item of the
737  * menu when created
738  */
739 static void 
740 on_account_update (TnyAccountStore *account_store, 
741                    gchar *accout_name,
742                    gpointer user_data)
743 {
744         ModestMainWindow *self;
745         ModestMainWindowPrivate *priv;
746         ModestWindowPrivate *parent_priv;
747         TnyList *account_list;
748         GtkWidget *item, *send_receive_button;
749         TnyIterator *iter;
750         ModestAccountMgr *mgr;
751         gchar *default_account;
752
753         self = MODEST_MAIN_WINDOW (user_data);
754         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
755         parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
756
757         /* If there is no toolbar then exit */
758         if (!parent_priv->toolbar)
759                 return;
760
761         if (priv->accounts_popup && gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)) ) {
762                 /* gtk_menu_detach will also unreference the popup, 
763                  * so we can forget about this instance, and create a new one later:
764                  */
765                 gtk_menu_detach (GTK_MENU (priv->accounts_popup));
766                 priv->accounts_popup = NULL;
767         }
768
769         /* Get accounts */
770         account_list = tny_simple_list_new ();
771         tny_account_store_get_accounts (account_store, 
772                                         account_list, 
773                                         TNY_ACCOUNT_STORE_STORE_ACCOUNTS);
774
775         /* If there is only one account do not show any menu */
776         if (tny_list_get_length (account_list) <= 1)
777                 goto free;
778         
779         /* Get send receive button */
780         send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
781                                                           "/ToolBar/ToolbarSendReceive");
782
783         /* Create the menu */
784         priv->accounts_popup = gtk_menu_new ();
785         item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
786         gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
787         item = gtk_separator_menu_item_new ();
788         gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
789
790         iter = tny_list_create_iterator (account_list);
791         mgr = modest_runtime_get_account_mgr ();
792         default_account = modest_account_mgr_get_default_account (mgr);
793
794         do {
795                 TnyAccount *acc = NULL;
796                 const gchar *acc_name = NULL;
797
798                 /* Create tool item */
799                 acc = TNY_ACCOUNT (tny_iterator_get_current (iter));
800                 if (acc)
801                         acc_name = tny_account_get_name (acc);
802
803                 /* Create display name */
804                 gchar *display_name = NULL;
805                 if (acc_name) {
806                         if (default_account && !(strcmp (default_account, acc_name) == 0))
807                                 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"), acc_name);
808                         else
809                                 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"), acc_name);
810                 }
811                 else
812                 {
813                         /* TODO: This probably should never happen: */
814                         display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"), "");
815                 }
816                 
817
818                 item = gtk_menu_item_new_with_label (display_name);
819
820                 /* Free */
821                 g_free (display_name);
822                 g_object_unref (acc);
823
824                 /* Append item */
825                 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
826
827                 /* Go to next */
828                 tny_iterator_next (iter);
829
830         } while (!tny_iterator_is_done (iter));
831
832         g_object_unref (iter);
833
834         /* Mandatory in order to view the menu contents */
835         gtk_widget_show_all (priv->accounts_popup);
836
837         /* Setup tap_and_hold */
838         gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
839
840  free:
841
842         /* Free */
843         g_object_unref (account_list);
844 }
845
846 /* 
847  * This function manages the key events used to navigate between
848  * header and folder views (when the window is in split view)
849  *
850  * FROM         KEY        ACTION
851  * -------------------------------------------------
852  * HeaderView   GDK_Left   Move focus to folder view
853  * FolderView   GDK_Right  Move focus to header view
854  *
855  * There is no need to scroll to selected row, the widgets will be the
856  * responsibles of doing that (probably managing the focus-in event
857  */
858 static gboolean 
859 on_inner_widgets_key_pressed (GtkWidget *widget,
860                               GdkEventKey *event,
861                               gpointer user_data)
862 {
863         ModestMainWindowPrivate *priv;
864
865         priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
866
867         /* Do nothing if we're in SIMPLE style */
868         if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
869                 return FALSE;
870
871         if (MODEST_IS_HEADER_VIEW (widget) && event->keyval == GDK_Left)
872                 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
873         else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
874                 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
875
876         return FALSE;
877 }
878
879 static void
880 set_alignment (GtkWidget *widget,
881                gpointer data)
882 {
883         gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
884         gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
885 }
886
887 static GtkWidget *
888 create_details_widget (TnyAccount *account)
889 {
890         GtkWidget *vbox;
891         gchar *label;
892
893         vbox = gtk_vbox_new (FALSE, 0);
894
895         /* Account description */
896         if (!strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
897                 gchar *device_name;
898
899                 /* Get device name */
900                 device_name = modest_conf_get_string (modest_runtime_get_conf(),
901                                                       MODEST_CONF_DEVICE_NAME, NULL);
902    
903                 label = g_strdup_printf ("%s: %s",
904                                          _("mcen_fi_localroot_description"),
905                                          device_name);
906                 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
907                 g_free (device_name);
908                 g_free (label);
909         } else if (!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
910                 /* TODO: MMC ? */
911                 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new ("FIXME: MMC ?"), FALSE, FALSE, 0);
912         } else {
913                 GString *proto;
914
915                 /* Put proto in uppercase */
916                 proto = g_string_new (tny_account_get_proto (account));
917                 proto = g_string_ascii_up (proto);
918
919                 label = g_strdup_printf ("%s %s: %s", 
920                                          proto->str,
921                                          _("mcen_fi_remoteroot_account"),
922                                          tny_account_get_name (account));
923                 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
924                 g_string_free (proto, TRUE);
925                 g_free (label);
926         }
927
928         /* Message count */
929         label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_messages"), 
930                                  modest_tny_account_get_message_count (account));
931         gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
932         g_free (label);
933
934         /* Folder count */
935         label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_folders"), 
936                                  modest_tny_account_get_folder_count (account));
937         gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
938         g_free (label);
939
940         /* Size / Date */
941         if (!strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
942                 /* FIXME: format size */
943                 label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_size"), 
944                                          modest_tny_account_get_local_size (account));
945                 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
946                 g_free (label);
947         } else if (!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
948                 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new ("FIXME: MMC ?"), FALSE, FALSE, 0);
949         } else {
950                 label = g_strdup_printf ("%s: %s", _("mcen_ti_lastupdated"), "08/08/08");
951                 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
952                 g_free (label);
953         }
954
955         /* Set alignment */
956         gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
957
958         return vbox;
959 }
960
961 void 
962 modest_main_window_set_contents_style (ModestMainWindow *self, 
963                                        ModestMainWindowContentsStyle style)
964 {
965         ModestMainWindowPrivate *priv;
966         GtkWidget *content;
967         TnyAccount *account;
968
969         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
970
971         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
972
973         /* We allow to set the same content style than the previously
974            set if there are details, because it could happen when we're
975            selecting different accounts consecutively */
976         if ((priv->contents_style == style) &&
977             (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS))
978                 return;
979
980         /* Remove previous child. Delete it if it was an account
981            details widget */
982         content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
983         if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
984                 g_object_ref (content);
985         gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
986
987         priv->contents_style = style;
988
989         switch (priv->contents_style) {
990         case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
991                 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
992                 break;
993         case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
994                 /* TODO: show here account details */
995                 account = TNY_ACCOUNT (modest_folder_view_get_selected (priv->folder_view));
996                 priv->details_widget = create_details_widget (account);
997
998                 wrap_in_scrolled_window (priv->contents_widget, 
999                                          priv->details_widget);
1000                 break;
1001         default:
1002                 g_return_if_reached ();
1003         }
1004
1005         /* Show */
1006         gtk_widget_show_all (priv->contents_widget);
1007 }
1008
1009 static void 
1010 on_configuration_key_changed (ModestConf* conf, 
1011                               const gchar *key, 
1012                               ModestConfEvent event, 
1013                               ModestMainWindow *self)
1014 {
1015         ModestMainWindowPrivate *priv;
1016         TnyAccount *account;
1017
1018         if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
1019                 return;
1020
1021         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1022
1023         if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1024                 return;
1025
1026         account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
1027         if (TNY_IS_ACCOUNT (account) &&
1028             !strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1029                 GList *children;
1030                 GtkLabel *label;
1031                 const gchar *device_name;
1032                 gchar *new_text;
1033                 
1034                 /* Get label */
1035                 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
1036                 label = GTK_LABEL (children->data);
1037                 
1038                 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1039                                                       MODEST_CONF_DEVICE_NAME, NULL);
1040                 
1041                 new_text = g_strdup_printf ("%s: %s",
1042                                             _("mcen_fi_localroot_description"),
1043                                             device_name);
1044                 
1045                 gtk_label_set_text (label, new_text);
1046                 gtk_widget_show (GTK_WIDGET (label));
1047                 
1048                 g_free (new_text);
1049                 g_list_free (children);
1050         }
1051 }
1052
1053 static void 
1054 set_toolbar_mode (ModestMainWindow *self, 
1055                   ModestToolBarModes mode)
1056 {
1057         ModestWindowPrivate *parent_priv;
1058         ModestMainWindowPrivate *priv;
1059         GtkAction *sort_action, *refresh_action, *cancel_action;
1060
1061         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1062
1063         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1064         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1065         
1066         sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1067         refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1068         cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1069
1070         /* Sets current toolbar mode */
1071         priv->current_toolbar_mode = mode;
1072
1073         /* Show and hide toolbar items */
1074         switch (mode) {
1075         case TOOLBAR_MODE_NORMAL:
1076                 if (sort_action) 
1077                         gtk_action_set_visible (sort_action, TRUE);
1078                 if (refresh_action) 
1079                         gtk_action_set_visible (refresh_action, TRUE);
1080                 if (priv->progress_toolitem) {
1081                         gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1082                         gtk_widget_hide (priv->progress_toolitem);
1083                 }
1084                 if (priv->progress_bar)
1085                         gtk_widget_hide (priv->progress_bar);                   
1086                 
1087                 if (cancel_action)
1088                         gtk_action_set_visible (cancel_action, FALSE);
1089                 break;
1090         case TOOLBAR_MODE_TRANSFER:
1091                 if (sort_action)
1092                         gtk_action_set_visible (sort_action, FALSE);
1093                 if (refresh_action)
1094                         gtk_action_set_visible (refresh_action, FALSE);
1095                 if (cancel_action)
1096                         gtk_action_set_visible (cancel_action, TRUE);
1097                 if (priv->progress_toolitem) {
1098                         gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1099                         gtk_widget_show (priv->progress_toolitem);
1100                 }
1101                 if (priv->progress_bar)
1102                         gtk_widget_show (priv->progress_bar);                   
1103                 break;
1104         default:
1105                 g_return_if_reached ();
1106         }
1107
1108         gtk_widget_show_all (GTK_WIDGET (self));
1109 }
1110
1111 static void
1112 cancel_progressbar (GtkToolButton *toolbutton,
1113                     ModestMainWindow *self)
1114 {
1115         GSList *tmp;
1116         ModestMainWindowPrivate *priv;
1117         
1118         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1119
1120         /* Get operation observers and cancel its current operation */
1121         tmp = priv->progress_widgets;
1122         while (tmp) {
1123                 modest_progress_object_cancel_current_operation (MODEST_PROGRESS_OBJECT(tmp->data));
1124                 tmp=g_slist_next(tmp);
1125         }
1126 }
1127
1128 static void
1129 on_queue_changed (ModestMailOperationQueue *queue,
1130                   ModestMailOperation *mail_op,
1131                   ModestMailOperationQueueNotification type,
1132                   ModestMainWindow *self)
1133 {
1134         ModestMainWindowPrivate *priv;
1135         ModestMailOperationId op_id;
1136         ModestToolBarModes mode;
1137         GSList *tmp;
1138         gboolean mode_changed = FALSE;
1139
1140         g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1141         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1142                
1143         /* Get toolbar mode from operation id*/
1144         op_id = modest_mail_operation_get_id (mail_op);
1145         switch (op_id) {
1146         case MODEST_MAIL_OPERATION_ID_SEND:
1147         case MODEST_MAIL_OPERATION_ID_RECEIVE:
1148                 mode = TOOLBAR_MODE_TRANSFER;
1149                 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
1150                         mode_changed = TRUE;
1151                 break;
1152         default:
1153                 mode = TOOLBAR_MODE_NORMAL;
1154                 
1155         }
1156                 
1157                        
1158         /* Add operation observers and change toolbar if neccessary*/
1159         tmp = priv->progress_widgets;
1160         switch (type) {
1161         case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
1162                 if (mode_changed)
1163                         set_toolbar_mode (MODEST_MAIN_WINDOW(self), mode);
1164                 if (mode == TOOLBAR_MODE_TRANSFER) {
1165                         while (tmp) {
1166                                 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1167                                                                       mail_op);
1168                                 tmp = g_slist_next (tmp);
1169                         }
1170                 }
1171                 break;
1172         case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED:
1173                 if (modest_mail_operation_queue_num_elements (queue) == 0)
1174                         set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1175                 if (mode == TOOLBAR_MODE_TRANSFER) {
1176                         while (tmp) {
1177                                 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1178                                                                          mail_op);
1179                                 tmp = g_slist_next (tmp);
1180                         }
1181                 }
1182                 break;
1183         }       
1184 }