8658f96fafe4725469f83ff83516cd5ed6ef1a27
[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 <string.h>
32 #include <gtk/gtkaboutdialog.h>
33 #include <gtk/gtktreeviewcolumn.h>
34
35 #include <modest-widget-memory.h>
36 #include <modest-icon-factory.h>
37
38 #include <widgets/modest-toolbar.h>
39
40 #include "modest-main-window.h"
41 #include "modest-account-view-window.h"
42 #include "modest-account-mgr.h"
43 #include "modest-conf.h"
44 #include "modest-edit-msg-window.h"
45 #include "modest-icon-names.h"
46 #include "modest-tny-platform-factory.h"
47 #include "modest-tny-msg-actions.h"
48 #include "modest-mail-operation.h"
49
50 /* 'private'/'protected' functions */
51 static void modest_main_window_class_init    (ModestMainWindowClass *klass);
52 static void modest_main_window_init          (ModestMainWindow *obj);
53 static void modest_main_window_finalize      (GObject *obj);
54
55 static void restore_sizes (ModestMainWindow *self);
56 static void save_sizes (ModestMainWindow *self);
57
58 /* list my signals */
59 enum {
60         /* MY_SIGNAL_1, */
61         /* MY_SIGNAL_2, */
62         LAST_SIGNAL
63 };
64
65 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
66 struct _ModestMainWindowPrivate {
67
68         GtkUIManager *ui_manager;
69
70         GtkWidget *toolbar;
71         GtkWidget *menu;
72
73         //GtkWidget *folder_paned;
74         GtkWidget *msg_paned;
75         GtkWidget *main_paned;
76         
77         ModestWidgetFactory *widget_factory;
78         TnyPlatformFactory *factory;
79   
80         ModestHeaderView *header_view;
81         ModestFolderView *folder_view;
82         ModestMsgView    *msg_preview;
83 };
84
85
86 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
87                                                 MODEST_TYPE_MAIN_WINDOW, \
88                                                 ModestMainWindowPrivate))
89 /* globals */
90 static GtkWindowClass *parent_class = NULL;
91
92 /* uncomment the following if you have defined any signals */
93 /* static guint signals[LAST_SIGNAL] = {0}; */
94
95 GType
96 modest_main_window_get_type (void)
97 {
98         static GType my_type = 0;
99         if (!my_type) {
100                 static const GTypeInfo my_info = {
101                         sizeof(ModestMainWindowClass),
102                         NULL,           /* base init */
103                         NULL,           /* base finalize */
104                         (GClassInitFunc) modest_main_window_class_init,
105                         NULL,           /* class finalize */
106                         NULL,           /* class data */
107                         sizeof(ModestMainWindow),
108                         1,              /* n_preallocs */
109                         (GInstanceInitFunc) modest_main_window_init,
110                         NULL
111                 };
112                 my_type = g_type_register_static (HILDON_TYPE_WINDOW,
113                                                   "ModestMainWindow",
114                                                   &my_info, 0);
115         }
116         return my_type;
117 }
118
119 static void
120 modest_main_window_class_init (ModestMainWindowClass *klass)
121 {
122         GObjectClass *gobject_class;
123         gobject_class = (GObjectClass*) klass;
124
125         parent_class            = g_type_class_peek_parent (klass);
126         gobject_class->finalize = modest_main_window_finalize;
127
128         g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
129
130         /* signal definitions go here, e.g.: */
131 /*      signals[MY_SIGNAL_1] = */
132 /*              g_signal_new ("my_signal_1",....); */
133 /*      signals[MY_SIGNAL_2] = */
134 /*              g_signal_new ("my_signal_2",....); */
135 /*      etc. */
136 }
137
138 static void
139 modest_main_window_init (ModestMainWindow *obj)
140 {
141         ModestMainWindowPrivate *priv;
142
143         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
144         
145         priv->factory = modest_tny_platform_factory_get_instance ();
146 }
147
148 static void
149 modest_main_window_finalize (GObject *obj)
150 {
151         ModestMainWindowPrivate *priv;  
152         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
153         if (priv->widget_factory) {
154                 g_object_unref (G_OBJECT(priv->widget_factory));
155                 priv->widget_factory = NULL;
156         }
157
158         G_OBJECT_CLASS(parent_class)->finalize (obj);
159 }
160
161
162 static void
163 on_menu_about (GtkWidget *widget, gpointer data)
164 {
165         GtkWidget *about;
166         const gchar *authors[] = {
167                 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
168                 NULL
169         };      
170         about = gtk_about_dialog_new ();
171         gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
172         gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
173         gtk_about_dialog_set_copyright (
174                 GTK_ABOUT_DIALOG(about),
175                 _("Copyright (c) 2006, Nokia Corporation\n"
176                   "All rights reserved."));
177         gtk_about_dialog_set_comments ( GTK_ABOUT_DIALOG(about),
178                 _("a modest e-mail client\n\n"
179                   "design and implementation: Dirk-Jan C. Binnema\n"
180                   "contributions from the fine people at KernelConcepts\n\n"
181                   "uses the tinymail email framework written by Philip van Hoof"));
182         gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
183         gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
184
185         gtk_dialog_run (GTK_DIALOG (about));
186         gtk_widget_destroy(about);
187 }
188
189
190 static void
191 on_menu_accounts (ModestMainWindow *self, guint action, GtkWidget *widget)
192 {
193         GtkWidget *account_win;
194         ModestMainWindowPrivate *priv;
195
196         g_return_if_fail (widget);
197         g_return_if_fail (self);
198         
199         priv        = MODEST_MAIN_WINDOW_GET_PRIVATE(self);     
200         account_win = modest_account_view_window_new (priv->widget_factory);
201
202         gtk_window_set_transient_for (GTK_WINDOW(account_win),
203                                       GTK_WINDOW(self));
204                                       
205         gtk_widget_show (account_win);
206 }
207
208
209 static void
210 on_menu_new_message (ModestMainWindow *self, guint action, GtkWidget *widget)
211 {
212         GtkWidget *msg_win;
213         ModestMainWindowPrivate *priv;
214
215         priv  = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
216
217         msg_win = modest_edit_msg_window_new (priv->widget_factory,
218                                               MODEST_EDIT_TYPE_NEW,
219                                               NULL);
220         gtk_widget_show (msg_win);
221 }
222
223 static void
224 on_menu_reply_forward (ModestMainWindow *self, guint action, GtkWidget *widget)
225 {
226         GtkWidget *msg_win;
227         ModestMainWindowPrivate *priv;
228         ModestHeaderView *header_view;
229         TnyList *header_list;
230         TnyIterator *iter;
231         const gchar *from;
232         gchar *reply_key, *forward_key;
233         ModestMailOperationReplyType reply_type;
234         ModestMailOperationForwardType forward_type;
235         ModestConf *conf;
236         GError *error;
237
238         priv  = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
239         conf = modest_tny_platform_factory_get_modest_conf_instance (priv->factory);
240
241         header_view = modest_widget_factory_get_header_view (priv->widget_factory);
242         header_list = modest_header_view_get_selected_headers (header_view);
243
244         /* Get reply and forward types */
245         error = NULL;
246         reply_key = g_strdup_printf ("%s/%s", MODEST_CONF_NAMESPACE, MODEST_CONF_REPLY_TYPE);
247         reply_type = modest_conf_get_int (conf, reply_key, &error);
248         if (error) {
249                 g_warning ("key %s not defined", reply_key);
250                 reply_type = MODEST_MAIL_OPERATION_REPLY_TYPE_CITE;
251                 g_error_free (error);
252                 error = NULL;
253         }
254         g_free (reply_key);
255         
256         forward_key = g_strdup_printf ("%s/%s", MODEST_CONF_NAMESPACE, MODEST_CONF_FORWARD_TYPE);
257         forward_type = modest_conf_get_int (conf, forward_key, NULL);
258         if (error) {
259                 g_warning ("key %s not defined", forward_key);
260                 reply_type = MODEST_MAIL_OPERATION_FORWARD_TYPE_INLINE;
261                 g_error_free (error);
262         }
263         g_free (forward_key);
264         
265         if (header_list) {
266                 iter = tny_list_create_iterator (header_list);
267                 do {
268                         TnyHeader *header, *new_header;
269                         TnyFolder *folder;
270                         TnyMsg    *msg, *new_msg;
271                         ModestEditType edit_type;
272
273                         /* Get msg from header */
274                         header = TNY_HEADER (tny_iterator_get_current (iter));
275                         folder = tny_header_get_folder (header);
276                         msg = tny_folder_get_msg (folder, header, NULL); /* FIXME */
277
278                         from = modest_folder_view_get_selected_account (priv->folder_view);
279
280                         /* FIXME: select proper action */
281                         switch (action) {
282                         case 1:
283                                 new_msg = 
284                                         modest_mail_operation_create_reply_mail (msg, from, reply_type,
285                                                                                  MODEST_MAIL_OPERATION_REPLY_MODE_SENDER);
286                                 edit_type = MODEST_EDIT_TYPE_REPLY;
287                                 break;
288                         case 2:
289                                 new_msg = 
290                                         modest_mail_operation_create_reply_mail (msg, from, reply_type,
291                                                                                  MODEST_MAIL_OPERATION_REPLY_MODE_ALL);
292                                 edit_type = MODEST_EDIT_TYPE_REPLY;
293                                 break;
294                         case 3:
295                                 new_msg = 
296                                         modest_mail_operation_create_forward_mail (msg, from, forward_type);
297                                 edit_type = MODEST_EDIT_TYPE_FORWARD;
298                                 break;
299                         default:
300                                 g_warning ("unexpected action type: %d", action);
301                         }
302
303                         /* Set from */
304                         new_header = tny_msg_get_header (new_msg);
305                         tny_header_set_from (new_header, 
306                                              modest_folder_view_get_selected_account (priv->folder_view));
307
308                         /* Show edit window */
309                         msg_win = modest_edit_msg_window_new (priv->widget_factory,
310                                                               edit_type,
311                                                               new_msg);
312                         gtk_widget_show (msg_win);
313
314                         /* Clean and go on */
315                         g_object_unref (new_msg);
316                         tny_iterator_next (iter);
317
318                 } while (!tny_iterator_is_done (iter));
319         }
320 }
321
322 static void
323 on_menu_quit (ModestMainWindow *self, guint action, GtkWidget *widget)
324 {
325         save_sizes (self);
326         gtk_widget_destroy (GTK_WIDGET(self));
327 }
328
329 static void
330 on_menu_delete (ModestMainWindow *self, guint action, GtkWidget *widget)
331 {
332         ModestMainWindowPrivate *priv;
333         ModestHeaderView *header_view;
334         TnyList *header_list;
335         TnyIterator *iter;
336         GtkTreeModel *model;
337
338         priv  = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
339
340         header_view = modest_widget_factory_get_header_view (priv->widget_factory);
341         header_list = modest_header_view_get_selected_headers (header_view);
342         
343         if (header_list) {
344                 iter = tny_list_create_iterator (header_list);
345                 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
346                 if (GTK_IS_TREE_MODEL_SORT (model))
347                         model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (model));
348                 do {
349                         TnyHeader *header;
350                         ModestMailOperation *mail_op;
351
352                         header = TNY_HEADER (tny_iterator_get_current (iter));
353                         /* TODO: thick grain mail operation involving
354                            a list of objects. Composite pattern ??? */
355                         mail_op = modest_mail_operation_new ();
356
357                         /* Move to trash */
358                         modest_mail_operation_remove_msg (mail_op, header, TRUE);
359
360                         /* Remove from tree model */
361                         tny_list_remove (TNY_LIST (model), G_OBJECT (header));
362
363                         g_object_unref (G_OBJECT (mail_op));
364                         g_object_unref (header);
365                         tny_iterator_next (iter);
366
367                 } while (!tny_iterator_is_done (iter));
368         }
369 }
370
371
372 /* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
373 static const gchar* UI_DEF=
374         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
375         "<ui>"
376         "  <popup>"
377         "    <menu name=\"Message\" \"MenuMessage\">"
378         "      <menuitem name=\"New\" action=\"on_menu_new_message\" />"
379         "    </menu>"
380 //      "    <menu name=\"JustifyMenu\" action=\"JustifyMenuAction\">"
381 //      "      <menuitem name=\"Left\" action=\"justify-left\"/>"
382 //      "      <menuitem name=\"Centre\" action=\"justify-center\"/>"
383 //      "      <menuitem name=\"Right\" action=\"justify-right\"/>"
384 //      "      <menuitem name=\"Fill\" action=\"justify-fill\"/>"
385 //      "    </menu>"
386         "  </popup>"
387         "</ui>";
388
389 static GtkMenu *
390 get_menu (ModestMainWindow *self)
391 {
392         GtkWidget *w;
393         int i = 0;
394         
395         ModestMainWindowPrivate *priv;
396         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
397
398         priv->ui_manager = gtk_ui_manager_new ();
399
400         gtk_ui_manager_add_ui_from_string (priv->ui_manager,
401                                            UI_DEF, strlen(UI_DEF),
402                                            NULL);
403
404         w = gtk_ui_manager_get_widget (priv->ui_manager, "/popup");
405         g_warning ("==> GtkMenu? ==> %s", GTK_IS_MENU(w) ? "yes" : "no"); 
406
407         return GTK_MENU(w);
408 }
409
410
411
412 static ModestHeaderView*
413 header_view_new (ModestMainWindow *self)
414 {
415         int i;
416         GList *columns = NULL;
417         ModestHeaderView *header_view;
418         ModestMainWindowPrivate *priv;
419         ModestHeaderViewColumn cols[] = {
420                 MODEST_HEADER_VIEW_COLUMN_MSGTYPE,
421                 MODEST_HEADER_VIEW_COLUMN_ATTACH,
422                 MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER
423 //              MODEST_HEADER_VIEW_COLUMN_FROM,
424 //              MODEST_HEADER_VIEW_COLUMN_SUBJECT,
425 //              MODEST_HEADER_VIEW_COLUMN_RECEIVED_DATE
426         };
427         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
428         
429         for (i = 0 ; i != sizeof(cols) / sizeof(ModestHeaderViewColumn); ++i)
430                 columns = g_list_append (columns, GINT_TO_POINTER(cols[i]));
431
432         header_view = modest_widget_factory_get_header_view (priv->widget_factory);
433         modest_header_view_set_columns (header_view, columns);
434         g_list_free (columns);
435
436         return header_view;
437 }
438
439
440 static void
441 on_toolbar_button_clicked (ModestToolbar *toolbar, ModestToolbarButton button_id,
442                            ModestMainWindow *self)
443 {
444         GtkTreeSelection *sel;
445         GtkTreeIter iter;
446         GtkTreeModel *model;
447         ModestMainWindowPrivate *priv;
448
449         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
450         
451         switch (button_id) {
452         case MODEST_TOOLBAR_BUTTON_NEW_MAIL:
453                 on_menu_new_message (self, 0, NULL);
454                 break;
455         case MODEST_TOOLBAR_BUTTON_REPLY:
456                 on_menu_reply_forward (self, 1, NULL);
457                 break;
458         case MODEST_TOOLBAR_BUTTON_REPLY_ALL:
459                 on_menu_reply_forward (self, 2, NULL);
460                 break;
461         case MODEST_TOOLBAR_BUTTON_FORWARD:
462                 on_menu_reply_forward (self, 3, NULL);
463                 break;
464         case MODEST_TOOLBAR_BUTTON_SEND_RECEIVE:
465                 
466
467         case MODEST_TOOLBAR_BUTTON_NEXT:
468                 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(priv->header_view));
469                 if (sel) {
470                         gtk_tree_selection_get_selected (sel, &model, &iter);
471                         gtk_tree_model_iter_next (model, &iter);
472                         gtk_tree_selection_select_iter (sel, &iter);
473                 }
474                 
475         case MODEST_TOOLBAR_BUTTON_PREV:
476         /*      if (sel) { */
477 /*                      gtk_tree_selection_get_selected (sel, &model, &iter); */
478 /*                      gtk_tree_model_iter_prev (model, &iter); */
479 /*                      gtk_tree_selection_select_iter (sel, &iter); */
480 /*              } */
481
482                 break;
483         case MODEST_TOOLBAR_BUTTON_DELETE:
484                 on_menu_delete (self, 0, GTK_WIDGET (toolbar));
485                 break;
486
487         default:
488                 g_printerr ("modest: key %d pressed\n", button_id);
489         }
490 }
491
492 static ModestToolbar*
493 toolbar_new (ModestMainWindow *self)
494 {
495         int i;
496         ModestToolbar *toolbar;
497         GSList *buttons = NULL;
498         ModestMainWindowPrivate *priv;
499
500         ModestToolbarButton button_ids[] = {
501                 MODEST_TOOLBAR_BUTTON_NEW_MAIL,
502                 MODEST_TOOLBAR_BUTTON_REPLY,
503                 MODEST_TOOLBAR_BUTTON_REPLY_ALL,
504                 MODEST_TOOLBAR_BUTTON_FORWARD,
505                 MODEST_TOOLBAR_SEPARATOR,
506                 MODEST_TOOLBAR_BUTTON_SEND_RECEIVE,
507                 MODEST_TOOLBAR_SEPARATOR,
508                 MODEST_TOOLBAR_BUTTON_PREV,
509                 MODEST_TOOLBAR_BUTTON_NEXT,
510                 MODEST_TOOLBAR_SEPARATOR,               
511                 MODEST_TOOLBAR_BUTTON_DELETE
512         };              
513         
514         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
515
516         for (i = 0 ; i != sizeof(button_ids) / sizeof(ModestToolbarButton); ++i)
517                 buttons = g_slist_append (buttons, GINT_TO_POINTER(button_ids[i]));
518         
519         toolbar = modest_widget_factory_get_main_toolbar (priv->widget_factory, buttons);
520         g_slist_free (buttons);
521         
522         g_signal_connect (G_OBJECT(toolbar), "button_clicked",
523                           G_CALLBACK(on_toolbar_button_clicked), self);
524         
525         return toolbar;
526 }
527
528
529
530 static void
531 restore_sizes (ModestMainWindow *self)
532 {
533         ModestConf *conf;
534         ModestMainWindowPrivate *priv;
535         
536         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
537         conf = modest_tny_platform_factory_get_modest_conf_instance (priv->factory);
538
539         modest_widget_memory_restore_settings (conf,GTK_WIDGET(self),
540                                                "modest-main-window");
541         modest_widget_memory_restore_settings (conf, GTK_WIDGET(priv->msg_paned),
542                                                "modest-msg-paned");
543         modest_widget_memory_restore_settings (conf, GTK_WIDGET(priv->main_paned),
544                                                "modest-main-paned");
545 }
546
547
548 static void
549 save_sizes (ModestMainWindow *self)
550 {
551         ModestMainWindowPrivate *priv;
552         ModestConf *conf;
553         
554         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
555         conf = modest_tny_platform_factory_get_modest_conf_instance (priv->factory);
556         
557         modest_widget_memory_save_settings (conf,GTK_WIDGET(self),
558                                             "modest-main-window");
559         modest_widget_memory_save_settings (conf, GTK_WIDGET(priv->msg_paned),
560                                             "modest-msg-paned");
561         modest_widget_memory_save_settings (conf, GTK_WIDGET(priv->main_paned),
562                                             "modest-main-paned");
563 }
564
565 static GtkWidget*
566 wrapped_in_scrolled_window (GtkWidget *widget, gboolean needs_viewport)
567 {
568         GtkWidget *win;
569
570         win = gtk_scrolled_window_new (NULL, NULL);
571         gtk_scrolled_window_set_policy
572                 (GTK_SCROLLED_WINDOW (win),GTK_POLICY_NEVER,
573                  GTK_POLICY_AUTOMATIC);
574         
575         if (needs_viewport)
576                 gtk_scrolled_window_add_with_viewport
577                         (GTK_SCROLLED_WINDOW(win), widget);
578         else
579                 gtk_container_add (GTK_CONTAINER(win),
580                                    widget);
581
582         return win;
583 }
584
585
586 static gboolean
587 on_delete_event (GtkWidget *widget, GdkEvent  *event, ModestMainWindow *self)
588 {
589         save_sizes (self);
590         return FALSE;
591 }
592
593
594 GtkWidget*
595 modest_main_window_new (ModestWidgetFactory *widget_factory)
596 {
597         GObject *obj;
598         ModestMainWindowPrivate *priv;
599         
600         GtkWidget *main_vbox;
601         GtkWidget *status_hbox;
602         GtkWidget *header_win, *folder_win, *favorites_win;
603         
604         g_return_val_if_fail (widget_factory, NULL);
605
606         obj  = g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL);
607         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
608
609         g_object_ref (widget_factory);
610         priv->widget_factory = widget_factory;
611
612         /* widgets from factory */
613         priv->folder_view = modest_widget_factory_get_folder_view (widget_factory);
614         priv->header_view = header_view_new (MODEST_MAIN_WINDOW(obj));
615         priv->msg_preview = modest_widget_factory_get_msg_preview (widget_factory);
616         
617         folder_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->folder_view),
618                                                  FALSE);
619         header_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->header_view),
620                                                  FALSE);                                
621         /*menu */
622         priv->menu = get_menu (MODEST_MAIN_WINDOW(obj));
623         hildon_window_set_menu (HILDON_WINDOW(obj), GTK_MENU(priv->menu));
624         
625         priv->toolbar = GTK_WIDGET(toolbar_new (MODEST_MAIN_WINDOW(obj)));
626         
627         /* paned */
628         priv->msg_paned = gtk_vpaned_new ();
629         priv->main_paned = gtk_hpaned_new ();
630
631         gtk_paned_add1 (GTK_PANED(priv->main_paned), folder_win);
632         gtk_paned_add2 (GTK_PANED(priv->main_paned), priv->msg_paned);
633
634         gtk_paned_add1 (GTK_PANED(priv->msg_paned), header_win);
635         gtk_paned_add2 (GTK_PANED(priv->msg_paned), GTK_WIDGET(priv->msg_preview));
636
637         gtk_widget_show (GTK_WIDGET(priv->header_view));
638         gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
639
640         /* status bar / progress */
641         status_hbox = gtk_hbox_new (FALSE, 0);
642         gtk_box_pack_start (GTK_BOX(status_hbox),
643                             modest_widget_factory_get_folder_info_label (widget_factory),
644                             FALSE,FALSE, 6);
645         gtk_box_pack_start (GTK_BOX(status_hbox),
646                             modest_widget_factory_get_status_bar(widget_factory),
647                             TRUE, TRUE, 0);
648         gtk_box_pack_start (GTK_BOX(status_hbox),
649                             modest_widget_factory_get_progress_bar(widget_factory),
650                             FALSE, FALSE, 0);
651         gtk_box_pack_start (GTK_BOX(status_hbox),
652                           modest_widget_factory_get_online_toggle(widget_factory),
653                           FALSE, FALSE, 0);
654
655         /* putting it all together... */
656         main_vbox = gtk_vbox_new (FALSE, 6);
657         gtk_box_pack_start (GTK_BOX(main_vbox), priv->main_paned, TRUE, TRUE,0);
658         gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, FALSE, 0);        
659         gtk_box_pack_start (GTK_BOX(main_vbox), status_hbox, FALSE, FALSE, 0);
660         
661         gtk_container_add (GTK_CONTAINER(obj), main_vbox);
662         restore_sizes (MODEST_MAIN_WINDOW(obj));        
663
664         gtk_window_set_title (GTK_WINDOW(obj), "Modest");
665         gtk_window_set_icon  (GTK_WINDOW(obj),
666                               modest_icon_factory_get_icon (MODEST_APP_ICON));
667         
668         gtk_widget_show_all (main_vbox);
669
670         g_signal_connect (G_OBJECT(obj), "delete-event",
671                           G_CALLBACK(on_delete_event), obj);
672         
673         return GTK_WIDGET(obj);
674 }