* added beginnings of new experimental non-glade gtk+ UI
[modest] / src / gtk2 / modest-main-window.c
1 /* modest-main-window.c */
2
3 /* insert (c)/licensing information) */
4
5 #include "modest-main-window.h"
6 /* include other impl specific header files */
7
8 /* 'private'/'protected' functions */
9 static void modest_main_window_class_init    (ModestMainWindowClass *klass);
10 static void modest_main_window_init          (ModestMainWindow *obj);
11 static void modest_main_window_finalize      (GObject *obj);
12
13 /* list my signals */
14 enum {
15         /* MY_SIGNAL_1, */
16         /* MY_SIGNAL_2, */
17         LAST_SIGNAL
18 };
19
20 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
21 struct _ModestMainWindowPrivate {
22         GtkWidget *toolbar;
23         GtkWidget *menubar;
24         GtkWidget *progress_bar;
25         GtkWidget *status_bar;
26         GtkWidget *folder_paned;
27         GtkWidget *msg_paned;
28
29         ModestWidgetFactory *widget_factory;
30         
31         ModestTnyHeaderTreeView *header_view;
32         ModestTnyFolderTreeView *folder_view;
33         ModestTnyMsgView        *msg_preview;
34 };
35
36
37 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
38                                                 MODEST_TYPE_MAIN_WINDOW, \
39                                                 ModestMainWindowPrivate))
40 /* globals */
41 static GtkWindowClass *parent_class = NULL;
42
43 /* uncomment the following if you have defined any signals */
44 /* static guint signals[LAST_SIGNAL] = {0}; */
45
46 GType
47 modest_main_window_get_type (void)
48 {
49         static GType my_type = 0;
50         if (!my_type) {
51                 static const GTypeInfo my_info = {
52                         sizeof(ModestMainWindowClass),
53                         NULL,           /* base init */
54                         NULL,           /* base finalize */
55                         (GClassInitFunc) modest_main_window_class_init,
56                         NULL,           /* class finalize */
57                         NULL,           /* class data */
58                         sizeof(ModestMainWindow),
59                         1,              /* n_preallocs */
60                         (GInstanceInitFunc) modest_main_window_init,
61                 };
62                 my_type = g_type_register_static (GTK_TYPE_WINDOW,
63                                                   "ModestMainWindow",
64                                                   &my_info, 0);
65         }
66         return my_type;
67 }
68
69 static void
70 modest_main_window_class_init (ModestMainWindowClass *klass)
71 {
72         GObjectClass *gobject_class;
73         gobject_class = (GObjectClass*) klass;
74
75         parent_class            = g_type_class_peek_parent (klass);
76         gobject_class->finalize = modest_main_window_finalize;
77
78         g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
79
80         /* signal definitions go here, e.g.: */
81 /*      signals[MY_SIGNAL_1] = */
82 /*              g_signal_new ("my_signal_1",....); */
83 /*      signals[MY_SIGNAL_2] = */
84 /*              g_signal_new ("my_signal_2",....); */
85 /*      etc. */
86 }
87
88 static void
89 modest_main_window_init (ModestMainWindow *obj)
90 {
91         ModestMainWindowPrivate *priv;
92
93         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
94
95         priv->widget_factory = NULL;
96 }
97
98 static void
99 modest_main_window_finalize (GObject *obj)
100 {
101         ModestMainWindowPrivate *priv;
102         
103         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
104
105         if (priv->widget_factory) {
106                 g_object_unref (G_OBJECT(priv->widget_factory));
107                 priv->widget_factory = NULL;
108         }
109                 
110         G_OBJECT_CLASS(parent_class)->finalize (obj);
111 }
112
113 /* Obligatory basic callback */
114 static void print_hello( GtkWidget *w,
115                          gpointer   data )
116 {
117         g_message ("Hello, World!\n");
118 }
119
120 /* For the check button */
121 static void print_toggle( gpointer   callback_data,
122                           guint      callback_action,
123                           GtkWidget *menu_item )
124 {
125    g_message ("Check button state - %d\n",
126               GTK_CHECK_MENU_ITEM (menu_item)->active);
127 }
128
129 /* For the radio buttons */
130 static void print_selected( gpointer   callback_data,
131                             guint      callback_action,
132                             GtkWidget *menu_item )
133 {
134    if(GTK_CHECK_MENU_ITEM(menu_item)->active)
135      g_message ("Radio button %d selected\n", callback_action);
136 }
137
138 /* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
139 static GtkItemFactoryEntry menu_items[] = {
140         { "/_File",         NULL,         NULL,           0, "<Branch>" },
141         { "/File/_New",     "<control>N", print_hello,    0, "<StockItem>", GTK_STOCK_NEW },
142         { "/File/_Open",    "<control>O", print_hello,    0, "<StockItem>", GTK_STOCK_OPEN },
143         { "/File/_Save",    "<control>S", print_hello,    0, "<StockItem>", GTK_STOCK_SAVE },
144         { "/File/Save _As", NULL,         NULL,           0, "<Item>" },
145         { "/File/sep1",     NULL,         NULL,           0, "<Separator>" },
146         { "/File/_Quit",    "<CTRL>Q", gtk_main_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
147         { "/_Edit",         NULL,         NULL,           0, "<Branch>" },
148         { "/Edit/_Undo",    "<control>Z", print_hello,    0, "<StockItem>", GTK_STOCK_UNDO },
149         { "/Edit/_Redo",    "<shift><control>Z", print_hello,    0, "<StockItem>", GTK_STOCK_REDO },
150         { "/File/sep1",     NULL,         NULL,           0, "<Separator>" },
151         
152         { "/Edit/Cut",    "<control>S", print_hello,    0, "<StockItem>", GTK_STOCK_SAVE },
153         { "/Edit/Copy",    NULL,         NULL,           0, "<Item>" },
154         { "/Edit/Paste",     NULL,         NULL,           0, "<Separator>" },
155         { "/Edit/Delete",    "<CTRL>Q", gtk_main_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
156         { "/Edit/Select all",    "<CTRL>A", gtk_main_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
157         { "/Edit/Deelect all",    "<Shift><CTRL>A", gtk_main_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
158         
159         { "/_Options",      NULL,         NULL,           0, "<Branch>" },
160         { "/Options/tear",  NULL,         NULL,           0, "<Tearoff>" },
161         { "/Options/Check", NULL,         print_toggle,   1, "<CheckItem>" },
162         { "/Options/sep",   NULL,         NULL,           0, "<Separator>" },
163         { "/Options/Rad1",  NULL,         print_selected, 1, "<RadioItem>" },
164         { "/Options/Rad2",  NULL,         print_selected, 2, "/Options/Rad1" },
165         { "/Options/Rad3",  NULL,         print_selected, 3, "/Options/Rad1" },
166         { "/_Help",         NULL,         NULL,           0, "<LastBranch>" },
167         { "/_Help/About",   NULL,         NULL,           0, "<Item>" },
168 };
169 static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
170
171
172 static GtkWidget *
173 menubar_new (ModestMainWindow *self)
174 {
175         GtkItemFactory *item_factory;
176         GtkAccelGroup *accel_group;
177         
178         /* Make an accelerator group (shortcut keys) */
179         accel_group = gtk_accel_group_new ();
180         
181         /* Make an ItemFactory (that makes a menubar) */
182         item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
183                                              accel_group);
184         
185         /* This function generates the menu items. Pass the item factory,
186            the number of items in the array, the array itself, and any
187            callback data for the the menu items. */
188         gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
189         
190         ///* Attach the new accelerator group to the window. */
191         gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
192         
193         /* Finally, return the actual menu bar created by the item factory. */
194         return gtk_item_factory_get_widget (item_factory, "<main>");
195 }
196
197
198
199
200 static ModestTnyHeaderTreeView*
201 header_view_new (ModestMainWindow *self)
202 {
203         int i;
204         GSList *columns = NULL;
205         ModestTnyHeaderTreeView *header_view;
206         ModestMainWindowPrivate *priv;
207         ModestTnyHeaderTreeViewColumn cols[] = {
208                 MODEST_TNY_HEADER_TREE_VIEW_COLUMN_MSGTYPE,
209                 MODEST_TNY_HEADER_TREE_VIEW_COLUMN_ATTACH,
210                 MODEST_TNY_HEADER_TREE_VIEW_COLUMN_FROM,
211                 MODEST_TNY_HEADER_TREE_VIEW_COLUMN_SUBJECT,
212                 MODEST_TNY_HEADER_TREE_VIEW_COLUMN_RECEIVED_DATE
213         };
214
215         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
216         
217         for (i = 0 ; i != sizeof(cols) / sizeof(ModestTnyHeaderTreeViewColumn); ++i)
218                 columns = g_slist_append (columns, GINT_TO_POINTER(cols[i]));
219
220         header_view = modest_widget_factory_get_header_tree_widget (priv->widget_factory);
221         modest_tny_header_tree_view_set_columns (header_view, columns);
222         g_slist_free (columns);
223
224         return header_view;
225 }
226
227
228
229 GtkWidget*
230 modest_main_window_new (ModestWidgetFactory *factory)
231 {
232         GObject *obj;
233         ModestMainWindowPrivate *priv;
234         
235         GtkWidget *main_vbox;
236         GtkWidget *main_paned;
237         GtkWidget *status_hbox;
238         GtkWidget *header_win, *folder_win; 
239         
240         g_return_val_if_fail (factory, NULL);
241
242         obj  = g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL);
243         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
244
245         g_object_ref (factory);
246         priv->widget_factory = factory;
247
248         /* widgets from factory */
249         priv->folder_view = modest_widget_factory_get_folder_tree_widget (factory);
250         priv->header_view = header_view_new (MODEST_MAIN_WINDOW(obj));
251         priv->msg_preview = modest_widget_factory_get_msg_preview_widget (factory);
252         folder_win = gtk_scrolled_window_new (NULL,NULL);
253         gtk_container_add (GTK_CONTAINER(folder_win), GTK_WIDGET(priv->folder_view));
254         header_win = gtk_scrolled_window_new (NULL,NULL);
255         gtk_container_add (GTK_CONTAINER(header_win), GTK_WIDGET(priv->header_view));
256                            
257         /* tool/menubar */
258         priv->menubar = menubar_new (MODEST_MAIN_WINDOW(obj));
259         priv->toolbar = gtk_toolbar_new ();
260
261         /* paned */
262         priv->folder_paned = gtk_vpaned_new ();
263         priv->msg_paned = gtk_vpaned_new ();
264         main_paned = gtk_hpaned_new ();
265         gtk_paned_add1 (GTK_PANED(main_paned), priv->folder_paned);
266         gtk_paned_add2 (GTK_PANED(main_paned), priv->msg_paned);
267         gtk_paned_add1 (GTK_PANED(priv->folder_paned), gtk_label_new ("Favourites"));
268         gtk_paned_add2 (GTK_PANED(priv->folder_paned), folder_win);
269         gtk_paned_add1 (GTK_PANED(priv->msg_paned), header_win);
270         gtk_paned_add2 (GTK_PANED(priv->msg_paned), GTK_WIDGET(priv->msg_preview));
271
272         gtk_widget_show (GTK_WIDGET(priv->header_view));
273                 
274         /* status bar / progress */
275         priv->status_bar   = gtk_statusbar_new ();
276         priv->progress_bar = gtk_progress_bar_new ();
277         status_hbox = gtk_hbox_new (TRUE, 5);
278         gtk_box_pack_start (GTK_BOX(status_hbox), priv->status_bar, FALSE, TRUE, 5);
279         gtk_box_pack_start (GTK_BOX(status_hbox), priv->progress_bar, FALSE, TRUE, 5);
280
281         
282         /* putting it all together... */
283         main_vbox = gtk_vbox_new (FALSE, 2);
284         gtk_box_pack_start (GTK_BOX(main_vbox), priv->menubar, FALSE, FALSE, 2);
285         gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, TRUE, 5);
286         gtk_box_pack_start (GTK_BOX(main_vbox), main_paned, TRUE, TRUE, 2);
287         gtk_box_pack_start (GTK_BOX(main_vbox), status_hbox, FALSE, FALSE, 5);
288         
289         gtk_container_add (GTK_CONTAINER(obj), main_vbox);
290         gtk_widget_show_all (main_vbox);
291         
292         gtk_window_set_title (GTK_WINDOW(obj), "modest");
293         gtk_window_set_default_size (GTK_WINDOW(obj), 800, 600);
294         
295         return GTK_WIDGET(obj);
296 }