ab4b0a5c1fc2179cafa523301a973d698b42010a
[modest] / src / gtk / 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 <modest-widget-memory.h>
31 #include <modest-icon-factory.h>
32
33 #include <widgets/modest-toolbar.h>
34
35 #include "modest-main-window.h"
36 #include "modest-account-view-window.h"
37 #include "modest-account-mgr.h"
38 #include "modest-conf.h"
39 #include "modest-edit-msg-window.h"
40 #include "modest-icon-names.h"
41 #include "modest-tny-platform-factory.h"
42
43 /* 'private'/'protected' functions */
44 static void modest_main_window_class_init    (ModestMainWindowClass *klass);
45 static void modest_main_window_init          (ModestMainWindow *obj);
46 static void modest_main_window_finalize      (GObject *obj);
47
48 static void restore_sizes (ModestMainWindow *self);
49 static void save_sizes (ModestMainWindow *self);
50
51 /* list my signals */
52 enum {
53         /* MY_SIGNAL_1, */
54         /* MY_SIGNAL_2, */
55         LAST_SIGNAL
56 };
57
58 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
59 struct _ModestMainWindowPrivate {
60
61         GtkWidget *toolbar;
62         GtkWidget *menubar;
63
64         GtkWidget *folder_paned;
65         GtkWidget *msg_paned;
66         GtkWidget *main_paned;
67         
68         ModestWidgetFactory *widget_factory;
69         TnyPlatformFactory *factory;
70   
71         ModestHeaderView *header_view;
72         ModestFolderView *folder_view;
73         ModestMsgView    *msg_preview;
74 };
75
76
77 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
78                                                 MODEST_TYPE_MAIN_WINDOW, \
79                                                 ModestMainWindowPrivate))
80 /* globals */
81 static GtkWindowClass *parent_class = NULL;
82
83 /* uncomment the following if you have defined any signals */
84 /* static guint signals[LAST_SIGNAL] = {0}; */
85
86 GType
87 modest_main_window_get_type (void)
88 {
89         static GType my_type = 0;
90         if (!my_type) {
91                 static const GTypeInfo my_info = {
92                         sizeof(ModestMainWindowClass),
93                         NULL,           /* base init */
94                         NULL,           /* base finalize */
95                         (GClassInitFunc) modest_main_window_class_init,
96                         NULL,           /* class finalize */
97                         NULL,           /* class data */
98                         sizeof(ModestMainWindow),
99                         1,              /* n_preallocs */
100                         (GInstanceInitFunc) modest_main_window_init,
101                         NULL
102                 };
103                 my_type = g_type_register_static (GTK_TYPE_WINDOW,
104                                                   "ModestMainWindow",
105                                                   &my_info, 0);
106         }
107         return my_type;
108 }
109
110 static void
111 modest_main_window_class_init (ModestMainWindowClass *klass)
112 {
113         GObjectClass *gobject_class;
114         gobject_class = (GObjectClass*) klass;
115
116         parent_class            = g_type_class_peek_parent (klass);
117         gobject_class->finalize = modest_main_window_finalize;
118
119         g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
120
121         /* signal definitions go here, e.g.: */
122 /*      signals[MY_SIGNAL_1] = */
123 /*              g_signal_new ("my_signal_1",....); */
124 /*      signals[MY_SIGNAL_2] = */
125 /*              g_signal_new ("my_signal_2",....); */
126 /*      etc. */
127 }
128
129 static void
130 modest_main_window_init (ModestMainWindow *obj)
131 {
132         ModestMainWindowPrivate *priv;
133
134         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
135         
136         priv->factory = modest_tny_platform_factory_get_instance ();
137 }
138
139 static void
140 modest_main_window_finalize (GObject *obj)
141 {
142         ModestMainWindowPrivate *priv;  
143         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
144         if (priv->widget_factory) {
145                 g_object_unref (G_OBJECT(priv->widget_factory));
146                 priv->widget_factory = NULL;
147         }
148
149         G_OBJECT_CLASS(parent_class)->finalize (obj);
150 }
151
152
153 static void
154 on_menu_about (GtkWidget *widget, gpointer data)
155 {
156         GtkWidget *about;
157         const gchar *authors[] = {
158                 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
159                 NULL
160         };      
161         about = gtk_about_dialog_new ();
162         gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
163         gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
164         gtk_about_dialog_set_copyright (
165                 GTK_ABOUT_DIALOG(about),
166                 _("Copyright (c) 2006, Nokia Corporation\n"
167                   "All rights reserved."));
168         gtk_about_dialog_set_comments ( GTK_ABOUT_DIALOG(about),
169                 _("a modest e-mail client\n\n"
170                   "design and implementation: Dirk-Jan C. Binnema\n"
171                   "contributions from the fine people at KernelConcepts\n\n"
172                   "uses the tinymail email framework written by Philip van Hoof"));
173         gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
174         gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
175
176         gtk_dialog_run (GTK_DIALOG (about));
177         gtk_widget_destroy(about);
178 }
179
180
181 static void
182 on_menu_accounts (ModestMainWindow *self, guint action, GtkWidget *widget)
183 {
184         GtkWidget *account_win;
185         ModestMainWindowPrivate *priv;
186
187         g_return_if_fail (widget);
188         g_return_if_fail (self);
189         
190         priv        = MODEST_MAIN_WINDOW_GET_PRIVATE(self);     
191         account_win = modest_account_view_window_new (priv->widget_factory);
192
193         gtk_window_set_transient_for (GTK_WINDOW(account_win),
194                                       GTK_WINDOW(self));
195                                       
196         gtk_widget_show (account_win);
197 }
198
199
200 static void
201 on_menu_new_message (ModestMainWindow *self, guint action, GtkWidget *widget)
202 {
203         GtkWidget *msg_win;
204         ModestMainWindowPrivate *priv;
205         ModestConf *conf;
206         TnyAccountStore *account_store;
207
208         priv  = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
209         conf = modest_tny_platform_factory_get_modest_conf_instance (priv->factory);
210         account_store = tny_platform_factory_new_account_store (priv->factory);
211
212         msg_win = modest_edit_msg_window_new (priv->widget_factory,
213                                               MODEST_EDIT_TYPE_NEW,
214                                               NULL);
215         gtk_widget_show (msg_win);
216 }
217
218 static void
219 on_menu_quit (ModestMainWindow *self, guint action, GtkWidget *widget)
220 {
221         save_sizes (self);
222         gtk_widget_destroy (GTK_WIDGET(self));
223 }
224
225
226 /* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
227 static GtkItemFactoryEntry menu_items[] = {
228         { "/_File",             NULL,                   NULL,           0, "<Branch>", NULL },
229         { "/File/_New",         "<control>N",           NULL,           0, "<StockItem>", GTK_STOCK_NEW },
230         { "/File/_Open",        "<control>O",           NULL,           0, "<StockItem>", GTK_STOCK_OPEN },
231         { "/File/_Save",        "<control>S",           NULL,           0, "<StockItem>", GTK_STOCK_SAVE },
232         { "/File/Save _As",     NULL,                   NULL,           0, "<Item>", NULL },
233         { "/File/sep1",         NULL,                   NULL,           0, "<Separator>", NULL },
234         { "/File/_Quit",        "<CTRL>Q",              on_menu_quit,  0, "<StockItem>", GTK_STOCK_QUIT },
235
236         { "/_Edit",             NULL,                   NULL,           0, "<Branch>", NULL },
237         { "/Edit/_Undo",        "<CTRL>Z",              NULL,           0, "<StockItem>", GTK_STOCK_UNDO },
238         { "/Edit/_Redo",        "<shift><CTRL>Z",       NULL,           0, "<StockItem>", GTK_STOCK_REDO },
239         { "/File/sep1",         NULL,                   NULL,           0, "<Separator>", NULL },
240         { "/Edit/Cut",          "<control>X",           NULL,           0, "<StockItem>", GTK_STOCK_CUT  },
241         { "/Edit/Copy",         "<CTRL>C",              NULL,           0, "<StockItem>", GTK_STOCK_COPY },
242         { "/Edit/Paste",        NULL,                   NULL,           0, "<StockItem>", GTK_STOCK_PASTE},
243         { "/Edit/sep1",         NULL,                   NULL,           0, "<Separator>", NULL },
244         { "/Edit/Delete",       "<CTRL>Q",              NULL,           0, "<Item>" ,NULL},
245         { "/Edit/Select all",   "<CTRL>A",              NULL,           0, "<Item>" ,NULL},
246         { "/Edit/Deelect all",  "<Shift><CTRL>A",       NULL,           0, "<Item>" ,NULL},
247
248         { "/_Actions",                NULL,             NULL,           0, "<Branch>" ,NULL},
249         { "/Actions/_New Message",    NULL,             on_menu_new_message,            0, "<Item>",NULL },
250         { "/Actions/_Reply",    NULL,                   NULL,           0, "<Item>" ,NULL},
251         { "/Actions/_Forward",  NULL,                   NULL,           0, "<Item>" ,NULL},
252         { "/Actions/_Bounce",   NULL,                   NULL,           0, "<Item>",NULL },     
253         
254         { "/_Options",           NULL,                  NULL,           0, "<Branch>" ,NULL},
255         { "/Options/_Accounts",  NULL,                  on_menu_accounts,0, "<Item>" ,NULL},
256         { "/Options/_Contacts",  NULL,                  NULL,           0, "<Item>" ,NULL },
257
258
259         { "/_Help",         NULL,                       NULL,           0, "<Branch>" ,NULL},
260         { "/_Help/About",   NULL,                       on_menu_about,  0, "<StockItem>", GTK_STOCK_ABOUT},
261 };
262
263 static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
264
265
266 static GtkWidget *
267 menubar_new (ModestMainWindow *self)
268 {
269         GtkItemFactory *item_factory;
270         GtkAccelGroup *accel_group;
271         
272         /* Make an accelerator group (shortcut keys) */
273         accel_group = gtk_accel_group_new ();
274         
275         /* Make an ItemFactory (that makes a menubar) */
276         item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
277                                              accel_group);
278         
279         /* This function generates the menu items. Pass the item factory,
280            the number of items in the array, the array itself, and any
281            callback data for the the menu items. */
282         gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, self);
283         
284         ///* Attach the new accelerator group to the window. */
285         gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
286         
287         /* Finally, return the actual menu bar created by the item factory. */
288         return gtk_item_factory_get_widget (item_factory, "<main>");
289 }
290
291
292
293
294 static ModestHeaderView*
295 header_view_new (ModestMainWindow *self)
296 {
297         int i;
298         GSList *columns = NULL;
299         ModestHeaderView *header_view;
300         ModestMainWindowPrivate *priv;
301         ModestHeaderViewColumn cols[] = {
302                 MODEST_HEADER_VIEW_COLUMN_MSGTYPE,
303                 MODEST_HEADER_VIEW_COLUMN_ATTACH,
304                 MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER
305 /*              MODEST_HEADER_VIEW_COLUMN_FROM, */
306 /*              MODEST_HEADER_VIEW_COLUMN_SUBJECT, */
307 /*              MODEST_HEADER_VIEW_COLUMN_RECEIVED_DATE */
308         };
309         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
310         
311         for (i = 0 ; i != sizeof(cols) / sizeof(ModestHeaderViewColumn); ++i)
312                 columns = g_slist_append (columns, GINT_TO_POINTER(cols[i]));
313
314         header_view = modest_widget_factory_get_header_view (priv->widget_factory);
315         modest_header_view_set_columns (header_view, columns);
316         g_slist_free (columns);
317
318         return header_view;
319 }
320
321 static void
322 on_toolbar_button_clicked (ModestToolbar *toolbar, ModestToolbarButton button_id,
323                            ModestMainWindow *self)
324 {
325         GtkTreeSelection *sel;
326         GtkTreeIter iter;
327         GtkTreeModel *model;
328         ModestMainWindowPrivate *priv;
329
330         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
331         
332         switch (button_id) {
333         case MODEST_TOOLBAR_BUTTON_NEW_MAIL:
334                 on_menu_new_message (self, 0, NULL);
335                 break;
336         case MODEST_TOOLBAR_BUTTON_REPLY:
337                 break;
338         case MODEST_TOOLBAR_BUTTON_REPLY_ALL:
339                 break;
340         case MODEST_TOOLBAR_BUTTON_FORWARD:
341                 break;
342         case MODEST_TOOLBAR_BUTTON_SEND_RECEIVE:
343                 
344
345         case MODEST_TOOLBAR_BUTTON_NEXT:
346                 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(priv->header_view));
347                 if (sel) {
348                         gtk_tree_selection_get_selected (sel, &model, &iter);
349                         gtk_tree_model_iter_next (model, &iter);
350                         gtk_tree_selection_select_iter (sel, &iter);
351                 }
352                 
353         case MODEST_TOOLBAR_BUTTON_PREV:
354         /*      if (sel) { */
355 /*                      gtk_tree_selection_get_selected (sel, &model, &iter); */
356 /*                      gtk_tree_model_iter_prev (model, &iter); */
357 /*                      gtk_tree_selection_select_iter (sel, &iter); */
358 /*              } */
359
360                 break;
361         case MODEST_TOOLBAR_BUTTON_DELETE:
362
363         default:
364                 g_printerr ("modest: key %d pressed\n", button_id);
365         }
366 }
367
368 static ModestToolbar*
369 toolbar_new (ModestMainWindow *self)
370 {
371         int i;
372         ModestToolbar *toolbar;
373         GSList *buttons = NULL;
374         ModestMainWindowPrivate *priv;
375
376         ModestToolbarButton button_ids[] = {
377                 MODEST_TOOLBAR_BUTTON_NEW_MAIL,
378                 MODEST_TOOLBAR_BUTTON_REPLY,
379                 MODEST_TOOLBAR_BUTTON_REPLY_ALL,
380                 MODEST_TOOLBAR_BUTTON_FORWARD,
381                 MODEST_TOOLBAR_SEPARATOR,
382                 MODEST_TOOLBAR_BUTTON_SEND_RECEIVE,
383                 MODEST_TOOLBAR_SEPARATOR,
384                 MODEST_TOOLBAR_BUTTON_PREV,
385                 MODEST_TOOLBAR_BUTTON_NEXT,
386                 MODEST_TOOLBAR_SEPARATOR,               
387                 MODEST_TOOLBAR_BUTTON_DELETE
388         };              
389         
390         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
391
392         for (i = 0 ; i != sizeof(button_ids) / sizeof(ModestToolbarButton); ++i)
393                 buttons = g_slist_append (buttons, GINT_TO_POINTER(button_ids[i]));
394         
395         toolbar = modest_widget_factory_get_main_toolbar (priv->widget_factory, buttons);
396         g_slist_free (buttons);
397         
398         g_signal_connect (G_OBJECT(toolbar), "button_clicked",
399                           G_CALLBACK(on_toolbar_button_clicked), self);
400         
401         return toolbar;
402 }
403
404
405
406 static void
407 restore_sizes (ModestMainWindow *self)
408 {
409         ModestConf *conf;
410         ModestMainWindowPrivate *priv;
411         
412         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
413         conf = modest_tny_platform_factory_get_modest_conf_instance (priv->factory);
414
415         modest_widget_memory_restore_settings (conf,GTK_WIDGET(self),
416                                                "modest-main-window");
417         modest_widget_memory_restore_settings (conf, GTK_WIDGET(priv->folder_paned),
418                                                "modest-folder-paned");
419         modest_widget_memory_restore_settings (conf, GTK_WIDGET(priv->msg_paned),
420                                                "modest-msg-paned");
421         modest_widget_memory_restore_settings (conf, GTK_WIDGET(priv->main_paned),
422                                                "modest-main-paned");
423 }
424
425
426 static void
427 save_sizes (ModestMainWindow *self)
428 {
429         ModestMainWindowPrivate *priv;
430         ModestConf *conf;
431         
432         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
433         conf = modest_tny_platform_factory_get_modest_conf_instance (priv->factory);
434         
435         modest_widget_memory_save_settings (conf,GTK_WIDGET(self),
436                                             "modest-main-window");
437         modest_widget_memory_save_settings (conf, GTK_WIDGET(priv->folder_paned),
438                                             "modest-folder-paned");
439         modest_widget_memory_save_settings (conf, GTK_WIDGET(priv->msg_paned),
440                                             "modest-msg-paned");
441         modest_widget_memory_save_settings (conf, GTK_WIDGET(priv->main_paned),
442                                             "modest-main-paned");
443 }
444
445 static GtkWidget*
446 wrapped_in_scrolled_window (GtkWidget *widget, gboolean needs_viewport)
447 {
448         GtkWidget *win;
449
450         win = gtk_scrolled_window_new (NULL, NULL);
451         gtk_scrolled_window_set_policy
452                 (GTK_SCROLLED_WINDOW (win),GTK_POLICY_NEVER,
453                  GTK_POLICY_AUTOMATIC);
454         
455         if (needs_viewport)
456                 gtk_scrolled_window_add_with_viewport
457                         (GTK_SCROLLED_WINDOW(win), widget);
458         else
459                 gtk_container_add (GTK_CONTAINER(win),
460                                    widget);
461
462         return win;
463 }
464
465
466 static gboolean
467 on_delete_event (GtkWidget *widget, GdkEvent  *event, ModestMainWindow *self)
468 {
469         save_sizes (self);
470         return FALSE;
471 }
472
473 static GtkWidget*
474 favorites_view ()
475 {
476         GtkWidget *favorites;
477         GtkTreeStore *store;
478         GtkTreeViewColumn *col;
479
480         store = gtk_tree_store_new (1, G_TYPE_STRING);
481         favorites = gtk_tree_view_new_with_model (GTK_TREE_MODEL(store));
482         col = gtk_tree_view_column_new_with_attributes (_("Favorites"),
483                                                         gtk_cell_renderer_text_new(),
484                                                         "text", 0, NULL);
485         
486         gtk_tree_view_append_column (GTK_TREE_VIEW(favorites), col);
487         gtk_widget_show_all (favorites);
488
489         g_object_unref (G_OBJECT(store));
490
491         return favorites;
492 }
493
494
495
496 GtkWidget*
497 modest_main_window_new (ModestWidgetFactory *widget_factory)
498 {
499         GObject *obj;
500         ModestMainWindowPrivate *priv;
501         
502         GtkWidget *main_vbox;
503         GtkWidget *status_hbox;
504         GtkWidget *header_win, *folder_win, *favorites_win;
505         
506         g_return_val_if_fail (widget_factory, NULL);
507
508         obj  = g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL);
509         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
510
511         g_object_ref (widget_factory);
512         priv->widget_factory = widget_factory;
513
514         /* widgets from factory */
515         priv->folder_view = modest_widget_factory_get_folder_view (widget_factory);
516         priv->header_view = header_view_new (MODEST_MAIN_WINDOW(obj));
517         priv->msg_preview = modest_widget_factory_get_msg_preview (widget_factory);
518         
519         folder_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->folder_view),
520                                                  FALSE);
521         header_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->header_view),
522                                                  FALSE);                           
523         favorites_win = wrapped_in_scrolled_window (favorites_view(),FALSE);                       
524         
525         /* tool/menubar */
526         priv->menubar = menubar_new (MODEST_MAIN_WINDOW(obj));
527         priv->toolbar = GTK_WIDGET(toolbar_new (MODEST_MAIN_WINDOW(obj)));
528
529         /* paned */
530         priv->folder_paned = gtk_vpaned_new ();
531         priv->msg_paned = gtk_vpaned_new ();
532         priv->main_paned = gtk_hpaned_new ();
533         gtk_paned_add1 (GTK_PANED(priv->main_paned), priv->folder_paned);
534         gtk_paned_add2 (GTK_PANED(priv->main_paned), priv->msg_paned);
535         gtk_paned_add1 (GTK_PANED(priv->folder_paned), favorites_win);
536         gtk_paned_add2 (GTK_PANED(priv->folder_paned), folder_win);
537         gtk_paned_add1 (GTK_PANED(priv->msg_paned), header_win);
538         gtk_paned_add2 (GTK_PANED(priv->msg_paned), GTK_WIDGET(priv->msg_preview));
539
540         gtk_widget_show (GTK_WIDGET(priv->header_view));
541         gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
542
543         
544         /* status bar / progress */
545         status_hbox = gtk_hbox_new (FALSE, 0);
546         gtk_box_pack_start (GTK_BOX(status_hbox),
547                             modest_widget_factory_get_folder_info_label (widget_factory),
548                             FALSE,FALSE, 6);
549         gtk_box_pack_start (GTK_BOX(status_hbox),
550                             modest_widget_factory_get_status_bar(widget_factory),
551                             TRUE, TRUE, 0);
552         gtk_box_pack_start (GTK_BOX(status_hbox),
553                             modest_widget_factory_get_progress_bar(widget_factory),
554                             FALSE, FALSE, 0);
555         gtk_box_pack_start (GTK_BOX(status_hbox),
556                           modest_widget_factory_get_online_toggle(widget_factory),
557                           FALSE, FALSE, 0);
558
559         /* putting it all together... */
560         main_vbox = gtk_vbox_new (FALSE, 6);
561         gtk_box_pack_start (GTK_BOX(main_vbox), priv->menubar, FALSE, FALSE, 0);
562         gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, FALSE, 0);
563         gtk_box_pack_start (GTK_BOX(main_vbox), priv->main_paned, TRUE, TRUE,0);
564         gtk_box_pack_start (GTK_BOX(main_vbox), status_hbox, FALSE, FALSE, 0);
565         
566         gtk_container_add (GTK_CONTAINER(obj), main_vbox);
567         restore_sizes (MODEST_MAIN_WINDOW(obj));        
568
569         gtk_window_set_title (GTK_WINDOW(obj), "Modest");
570         gtk_window_set_icon  (GTK_WINDOW(obj),
571                               modest_icon_factory_get_icon (MODEST_APP_ICON));
572         
573         gtk_widget_show_all (main_vbox);
574
575         g_signal_connect (G_OBJECT(obj), "delete-event",
576                           G_CALLBACK(on_delete_event), obj);
577         
578         return GTK_WIDGET(obj);
579 }