1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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.
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.
30 #include "modest-main-window.h"
31 #include "modest-account-view-window.h"
32 #include "modest-msg-window.h"
34 /* 'private'/'protected' functions */
35 static void modest_main_window_class_init (ModestMainWindowClass *klass);
36 static void modest_main_window_init (ModestMainWindow *obj);
37 static void modest_main_window_finalize (GObject *obj);
46 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
47 struct _ModestMainWindowPrivate {
50 GtkWidget *progress_bar;
51 GtkWidget *status_bar;
52 GtkWidget *folder_paned;
55 ModestWidgetFactory *widget_factory;
58 ModestHeaderView *header_view;
59 ModestFolderView *folder_view;
60 ModestMsgView *msg_preview;
64 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
65 MODEST_TYPE_MAIN_WINDOW, \
66 ModestMainWindowPrivate))
68 static GtkWindowClass *parent_class = NULL;
70 /* uncomment the following if you have defined any signals */
71 /* static guint signals[LAST_SIGNAL] = {0}; */
74 modest_main_window_get_type (void)
76 static GType my_type = 0;
78 static const GTypeInfo my_info = {
79 sizeof(ModestMainWindowClass),
81 NULL, /* base finalize */
82 (GClassInitFunc) modest_main_window_class_init,
83 NULL, /* class finalize */
84 NULL, /* class data */
85 sizeof(ModestMainWindow),
87 (GInstanceInitFunc) modest_main_window_init,
89 my_type = g_type_register_static (GTK_TYPE_WINDOW,
97 modest_main_window_class_init (ModestMainWindowClass *klass)
99 GObjectClass *gobject_class;
100 gobject_class = (GObjectClass*) klass;
102 parent_class = g_type_class_peek_parent (klass);
103 gobject_class->finalize = modest_main_window_finalize;
105 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
107 /* signal definitions go here, e.g.: */
108 /* signals[MY_SIGNAL_1] = */
109 /* g_signal_new ("my_signal_1",....); */
110 /* signals[MY_SIGNAL_2] = */
111 /* g_signal_new ("my_signal_2",....); */
116 modest_main_window_init (ModestMainWindow *obj)
118 ModestMainWindowPrivate *priv;
120 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
122 priv->widget_factory = NULL;
126 modest_main_window_finalize (GObject *obj)
128 ModestMainWindowPrivate *priv;
130 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
132 if (priv->widget_factory) {
133 g_object_unref (G_OBJECT(priv->widget_factory));
134 priv->widget_factory = NULL;
138 g_object_unref (G_OBJECT(priv->conf));
141 G_OBJECT_CLASS(parent_class)->finalize (obj);
146 on_menu_about (GtkWidget *widget, gpointer data)
150 about = gtk_about_dialog_new ();
151 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
152 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
153 gtk_about_dialog_set_copyright (
154 GTK_ABOUT_DIALOG(about),
155 _("Copyright (c) 2006, Nokia Corporation\n"
156 "All rights reserved."));
157 gtk_about_dialog_set_comments ( GTK_ABOUT_DIALOG(about),
158 _("a modest e-mail client"));
159 gtk_dialog_run (GTK_DIALOG (about));
160 gtk_widget_destroy(about);
165 on_menu_accounts (ModestMainWindow *self, guint action, GtkWidget *widget)
167 GtkWidget *account_win;
168 ModestMainWindowPrivate *priv;
170 g_return_if_fail (widget);
171 g_return_if_fail (self);
173 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
174 account_win = modest_account_view_window_new (priv->conf,
175 priv->widget_factory);
176 gtk_widget_show (account_win);
181 on_menu_new_message (ModestMainWindow *self, guint action, GtkWidget *widget)
185 msg_win = modest_msg_window_new (MODEST_MSG_WINDOW_TYPE_NEW,
188 gtk_widget_show (msg_win);
193 /* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
194 static GtkItemFactoryEntry menu_items[] = {
195 { "/_File", NULL, NULL, 0, "<Branch>" },
196 { "/File/_New", "<control>N", NULL, 0, "<StockItem>", GTK_STOCK_NEW },
197 { "/File/_Open", "<control>O", NULL, 0, "<StockItem>", GTK_STOCK_OPEN },
198 { "/File/_Save", "<control>S", NULL, 0, "<StockItem>", GTK_STOCK_SAVE },
199 { "/File/Save _As", NULL, NULL, 0, "<Item>" },
200 { "/File/sep1", NULL, NULL, 0, "<Separator>" },
201 { "/File/_Quit", "<CTRL>Q", gtk_main_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
203 { "/_Edit", NULL, NULL, 0, "<Branch>" },
204 { "/Edit/_Undo", "<CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_UNDO },
205 { "/Edit/_Redo", "<shift><CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_REDO },
206 { "/File/sep1", NULL, NULL, 0, "<Separator>" },
207 { "/Edit/Cut", "<control>X", NULL, 0, "<StockItem>", GTK_STOCK_CUT },
208 { "/Edit/Copy", "<CTRL>C", NULL, 0, "<StockItem>", GTK_STOCK_COPY },
209 { "/Edit/Paste", NULL, NULL, 0, "<StockItem>", GTK_STOCK_PASTE},
210 { "/Edit/sep1", NULL, NULL, 0, "<Separator>" },
211 { "/Edit/Delete", "<CTRL>Q", NULL, 0, "<Item>" },
212 { "/Edit/Select all", "<CTRL>A", NULL, 0, "<Item>" },
213 { "/Edit/Deelect all", "<Shift><CTRL>A", NULL, 0, "<Item>" },
215 { "/_Actions", NULL, NULL, 0, "<Branch>" },
216 { "/Actions/_New Message", NULL, on_menu_new_message, 0, "<Item>" },
217 { "/Actions/_Reply", NULL, NULL, 0, "<Item>" },
218 { "/Actions/_Forward", NULL, NULL, 0, "<Item>" },
219 { "/Actions/_Bounce", NULL, NULL, 0, "<Item>" },
221 { "/_Options", NULL, NULL, 0, "<Branch>" },
222 { "/Options/_Accounts", NULL, on_menu_accounts,0, "<Item>" },
223 { "/Options/_Contacts", NULL, NULL, 0, "<Item>" },
226 { "/_Help", NULL, NULL, 0, "<Branch>" },
227 { "/_Help/About", NULL, on_menu_about, 0, "<StockItem>", GTK_STOCK_ABOUT},
230 static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
234 menubar_new (ModestMainWindow *self)
236 GtkItemFactory *item_factory;
237 GtkAccelGroup *accel_group;
239 /* Make an accelerator group (shortcut keys) */
240 accel_group = gtk_accel_group_new ();
242 /* Make an ItemFactory (that makes a menubar) */
243 item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
246 /* This function generates the menu items. Pass the item factory,
247 the number of items in the array, the array itself, and any
248 callback data for the the menu items. */
249 gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, self);
251 ///* Attach the new accelerator group to the window. */
252 gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
254 /* Finally, return the actual menu bar created by the item factory. */
255 return gtk_item_factory_get_widget (item_factory, "<main>");
261 static ModestHeaderView*
262 header_view_new (ModestMainWindow *self)
265 GSList *columns = NULL;
266 ModestHeaderView *header_view;
267 ModestMainWindowPrivate *priv;
268 ModestHeaderViewColumn cols[] = {
269 MODEST_HEADER_VIEW_COLUMN_MSGTYPE,
270 MODEST_HEADER_VIEW_COLUMN_ATTACH,
271 MODEST_HEADER_VIEW_COLUMN_FROM,
272 MODEST_HEADER_VIEW_COLUMN_SUBJECT,
273 MODEST_HEADER_VIEW_COLUMN_RECEIVED_DATE
276 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
278 for (i = 0 ; i != sizeof(cols) / sizeof(ModestHeaderViewColumn); ++i)
279 columns = g_slist_append (columns, GINT_TO_POINTER(cols[i]));
281 header_view = modest_widget_factory_get_header_view (priv->widget_factory);
282 modest_header_view_set_columns (header_view, columns);
283 g_slist_free (columns);
290 set_sizes (ModestMainWindow *self)
292 ModestMainWindowPrivate *priv;
298 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
300 /* size of the whole window */
301 win_x = modest_conf_get_int_or_default (priv->conf,
302 MODEST_MAIN_WINDOW_WIDTH,
303 MODEST_MAIN_WINDOW_WIDTH_DEFAULT);
304 win_y = modest_conf_get_int_or_default (priv->conf,
305 MODEST_MAIN_WINDOW_HEIGHT,
306 MODEST_MAIN_WINDOW_HEIGHT_DEFAULT);
307 gtk_window_set_default_size (GTK_WINDOW(self), win_x, win_y);
309 /* size of the folder pane */
310 fol_x = modest_conf_get_int_or_default (priv->conf,
311 MODEST_FOLDER_PANED_WIDTH,
312 MODEST_FOLDER_PANED_WIDTH_DEFAULT);
313 fol_pos = modest_conf_get_int_or_default (priv->conf,
314 MODEST_FOLDER_PANED_DIVIDER_POS,
315 MODEST_FOLDER_PANED_DIVIDER_POS_DEFAULT);
316 if (1 > fol_x || fol_x > win_x || 1 > fol_pos || fol_pos > win_y) {
317 g_printerr ("modest: folder paned <x,pos> out of range: <%d,%d>\n",
320 /* slightly off... */
321 gtk_widget_set_size_request (priv->folder_paned, fol_x, win_y);
322 gtk_paned_set_position (GTK_PANED(priv->folder_paned),
326 /* size of the folder pane */
327 msg_x = modest_conf_get_int_or_default (priv->conf,
328 MODEST_MSG_PANED_WIDTH,
329 MODEST_MSG_PANED_WIDTH_DEFAULT);
330 msg_pos = modest_conf_get_int_or_default (priv->conf,
331 MODEST_MSG_PANED_DIVIDER_POS,
332 MODEST_MSG_PANED_DIVIDER_POS_DEFAULT);
333 if (1 > msg_x || msg_x > win_x || 1 > msg_pos || msg_pos > win_y) {
334 g_printerr ("modest: msg paned <x,pos> out of range: <%d,%d>\n",
337 /* slightly off... */
338 gtk_widget_set_size_request (priv->msg_paned,
340 gtk_paned_set_position (GTK_PANED(priv->msg_paned),
348 wrapped_in_scrolled_window (GtkWidget *widget, gboolean needs_viewport)
352 win = gtk_scrolled_window_new (NULL, NULL);
353 gtk_scrolled_window_set_policy
354 (GTK_SCROLLED_WINDOW (win),GTK_POLICY_NEVER,
355 GTK_POLICY_AUTOMATIC);
358 gtk_scrolled_window_add_with_viewport
359 (GTK_SCROLLED_WINDOW(win), widget);
361 gtk_container_add (GTK_CONTAINER(win),
368 modest_main_window_new (ModestWidgetFactory *factory, ModestConf *conf)
371 ModestMainWindowPrivate *priv;
373 GtkWidget *main_vbox;
374 GtkWidget *main_paned;
375 GtkWidget *status_hbox;
376 GtkWidget *header_win, *folder_win;
378 g_return_val_if_fail (factory, NULL);
379 g_return_val_if_fail (conf, NULL);
381 obj = g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL);
382 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
384 g_object_ref (factory);
385 priv->widget_factory = factory;
390 /* widgets from factory */
391 priv->folder_view = modest_widget_factory_get_folder_view (factory);
392 priv->header_view = header_view_new (MODEST_MAIN_WINDOW(obj));
393 priv->msg_preview = modest_widget_factory_get_msg_preview (factory);
395 folder_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->folder_view),
397 header_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->header_view),
400 priv->menubar = menubar_new (MODEST_MAIN_WINDOW(obj));
401 priv->toolbar = gtk_toolbar_new ();
404 priv->folder_paned = gtk_vpaned_new ();
405 priv->msg_paned = gtk_vpaned_new ();
406 main_paned = gtk_hpaned_new ();
407 gtk_paned_add1 (GTK_PANED(main_paned), priv->folder_paned);
408 gtk_paned_add2 (GTK_PANED(main_paned), priv->msg_paned);
409 gtk_paned_add1 (GTK_PANED(priv->folder_paned),
410 gtk_label_new (_("Favorites")));
411 gtk_paned_add2 (GTK_PANED(priv->folder_paned), folder_win);
412 gtk_paned_add1 (GTK_PANED(priv->msg_paned), header_win);
413 gtk_paned_add2 (GTK_PANED(priv->msg_paned), GTK_WIDGET(priv->msg_preview));
415 gtk_widget_show (GTK_WIDGET(priv->header_view));
417 /* status bar / progress */
418 priv->status_bar = gtk_statusbar_new ();
419 priv->progress_bar = gtk_progress_bar_new ();
420 status_hbox = gtk_hbox_new (TRUE, 5);
421 gtk_box_pack_start (GTK_BOX(status_hbox), priv->progress_bar, FALSE, TRUE, 5);
422 gtk_box_pack_start (GTK_BOX(status_hbox), priv->status_bar, FALSE, TRUE, 5);
424 /* putting it all together... */
425 main_vbox = gtk_vbox_new (FALSE, 2);
426 gtk_box_pack_start (GTK_BOX(main_vbox), priv->menubar, FALSE, FALSE, 2);
427 gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, TRUE, 5);
428 gtk_box_pack_start (GTK_BOX(main_vbox), main_paned, TRUE, TRUE, 2);
429 gtk_box_pack_start (GTK_BOX(main_vbox), status_hbox, FALSE, FALSE, 5);
431 gtk_container_add (GTK_CONTAINER(obj), main_vbox);
432 gtk_widget_show_all (main_vbox);
434 gtk_window_set_title (GTK_WINDOW(obj), "Modest");
436 set_sizes (MODEST_MAIN_WINDOW(obj));
437 return GTK_WIDGET(obj);