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-widget-memory.h>
31 #include <modest-icon-factory.h>
33 #include "modest-main-window.h"
34 #include "modest-account-view-window.h"
35 #include "modest-edit-msg-window.h"
36 #include "modest-icon-names.h"
39 /* 'private'/'protected' functions */
40 static void modest_main_window_class_init (ModestMainWindowClass *klass);
41 static void modest_main_window_init (ModestMainWindow *obj);
42 static void modest_main_window_finalize (GObject *obj);
44 static void restore_sizes (ModestMainWindow *self);
45 static void save_sizes (ModestMainWindow *self);
54 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
55 struct _ModestMainWindowPrivate {
60 GtkWidget *folder_paned;
62 GtkWidget *main_paned;
64 ModestWidgetFactory *widget_factory;
66 ModestAccountMgr *account_mgr;
68 ModestHeaderView *header_view;
69 ModestFolderView *folder_view;
70 ModestMsgView *msg_preview;
74 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
75 MODEST_TYPE_MAIN_WINDOW, \
76 ModestMainWindowPrivate))
78 static GtkWindowClass *parent_class = NULL;
80 /* uncomment the following if you have defined any signals */
81 /* static guint signals[LAST_SIGNAL] = {0}; */
84 modest_main_window_get_type (void)
86 static GType my_type = 0;
88 static const GTypeInfo my_info = {
89 sizeof(ModestMainWindowClass),
91 NULL, /* base finalize */
92 (GClassInitFunc) modest_main_window_class_init,
93 NULL, /* class finalize */
94 NULL, /* class data */
95 sizeof(ModestMainWindow),
97 (GInstanceInitFunc) modest_main_window_init,
100 my_type = g_type_register_static (GTK_TYPE_WINDOW,
108 modest_main_window_class_init (ModestMainWindowClass *klass)
110 GObjectClass *gobject_class;
111 gobject_class = (GObjectClass*) klass;
113 parent_class = g_type_class_peek_parent (klass);
114 gobject_class->finalize = modest_main_window_finalize;
116 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
118 /* signal definitions go here, e.g.: */
119 /* signals[MY_SIGNAL_1] = */
120 /* g_signal_new ("my_signal_1",....); */
121 /* signals[MY_SIGNAL_2] = */
122 /* g_signal_new ("my_signal_2",....); */
127 modest_main_window_init (ModestMainWindow *obj)
129 ModestMainWindowPrivate *priv;
131 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
133 priv->widget_factory = NULL;
135 priv->account_mgr = NULL;
139 modest_main_window_finalize (GObject *obj)
141 ModestMainWindowPrivate *priv;
142 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
143 if (priv->widget_factory) {
144 g_object_unref (G_OBJECT(priv->widget_factory));
145 priv->widget_factory = NULL;
148 g_object_unref (G_OBJECT(priv->conf));
152 if (priv->account_mgr) {
153 g_object_unref (G_OBJECT(priv->account_mgr));
154 priv->account_mgr = NULL;
157 G_OBJECT_CLASS(parent_class)->finalize (obj);
162 on_menu_about (GtkWidget *widget, gpointer data)
165 const gchar *authors[] = {
166 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
169 about = gtk_about_dialog_new ();
170 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
171 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
172 gtk_about_dialog_set_copyright (
173 GTK_ABOUT_DIALOG(about),
174 _("Copyright (c) 2006, Nokia Corporation\n"
175 "All rights reserved."));
176 gtk_about_dialog_set_comments ( GTK_ABOUT_DIALOG(about),
177 _("a modest e-mail client\n\n"
178 "design and implementation: Dirk-Jan C. Binnema\n"
179 "contributions from the fine people at KernelConcepts\n\n"
180 "uses the tinymail email framework written by Philip van Hoof"));
181 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
182 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
184 gtk_dialog_run (GTK_DIALOG (about));
185 gtk_widget_destroy(about);
190 on_menu_accounts (ModestMainWindow *self, guint action, GtkWidget *widget)
192 GtkWidget *account_win;
193 ModestMainWindowPrivate *priv;
195 g_return_if_fail (widget);
196 g_return_if_fail (self);
198 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
199 account_win = modest_account_view_window_new (priv->account_mgr,
200 priv->widget_factory);
202 gtk_window_set_transient_for (GTK_WINDOW(account_win),
205 gtk_widget_show (account_win);
210 on_menu_new_message (ModestMainWindow *self, guint action, GtkWidget *widget)
213 ModestMainWindowPrivate *priv;
215 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
217 msg_win = modest_edit_msg_window_new (priv->conf,
218 MODEST_EDIT_TYPE_NEW,
220 gtk_widget_show (msg_win);
224 on_menu_quit (ModestMainWindow *self, guint action, GtkWidget *widget)
231 /* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
232 static GtkItemFactoryEntry menu_items[] = {
233 { "/_File", NULL, NULL, 0, "<Branch>" },
234 { "/File/_New", "<control>N", NULL, 0, "<StockItem>", GTK_STOCK_NEW },
235 { "/File/_Open", "<control>O", NULL, 0, "<StockItem>", GTK_STOCK_OPEN },
236 { "/File/_Save", "<control>S", NULL, 0, "<StockItem>", GTK_STOCK_SAVE },
237 { "/File/Save _As", NULL, NULL, 0, "<Item>" },
238 { "/File/sep1", NULL, NULL, 0, "<Separator>" },
239 { "/File/_Quit", "<CTRL>Q", on_menu_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
241 { "/_Edit", NULL, NULL, 0, "<Branch>" },
242 { "/Edit/_Undo", "<CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_UNDO },
243 { "/Edit/_Redo", "<shift><CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_REDO },
244 { "/File/sep1", NULL, NULL, 0, "<Separator>" },
245 { "/Edit/Cut", "<control>X", NULL, 0, "<StockItem>", GTK_STOCK_CUT },
246 { "/Edit/Copy", "<CTRL>C", NULL, 0, "<StockItem>", GTK_STOCK_COPY },
247 { "/Edit/Paste", NULL, NULL, 0, "<StockItem>", GTK_STOCK_PASTE},
248 { "/Edit/sep1", NULL, NULL, 0, "<Separator>" },
249 { "/Edit/Delete", "<CTRL>Q", NULL, 0, "<Item>" },
250 { "/Edit/Select all", "<CTRL>A", NULL, 0, "<Item>" },
251 { "/Edit/Deelect all", "<Shift><CTRL>A", NULL, 0, "<Item>" },
253 { "/_Actions", NULL, NULL, 0, "<Branch>" },
254 { "/Actions/_New Message", NULL, on_menu_new_message, 0, "<Item>" },
255 { "/Actions/_Reply", NULL, NULL, 0, "<Item>" },
256 { "/Actions/_Forward", NULL, NULL, 0, "<Item>" },
257 { "/Actions/_Bounce", NULL, NULL, 0, "<Item>" },
259 { "/_Options", NULL, NULL, 0, "<Branch>" },
260 { "/Options/_Accounts", NULL, on_menu_accounts,0, "<Item>" },
261 { "/Options/_Contacts", NULL, NULL, 0, "<Item>" },
264 { "/_Help", NULL, NULL, 0, "<Branch>" },
265 { "/_Help/About", NULL, on_menu_about, 0, "<StockItem>", GTK_STOCK_ABOUT},
268 static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
272 menubar_new (ModestMainWindow *self)
274 GtkItemFactory *item_factory;
275 GtkAccelGroup *accel_group;
277 /* Make an accelerator group (shortcut keys) */
278 accel_group = gtk_accel_group_new ();
280 /* Make an ItemFactory (that makes a menubar) */
281 item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
284 /* This function generates the menu items. Pass the item factory,
285 the number of items in the array, the array itself, and any
286 callback data for the the menu items. */
287 gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, self);
289 ///* Attach the new accelerator group to the window. */
290 gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
292 /* Finally, return the actual menu bar created by the item factory. */
293 return gtk_item_factory_get_widget (item_factory, "<main>");
299 static ModestHeaderView*
300 header_view_new (ModestMainWindow *self)
303 GSList *columns = NULL;
304 ModestHeaderView *header_view;
305 ModestMainWindowPrivate *priv;
306 ModestHeaderViewColumn cols[] = {
307 MODEST_HEADER_VIEW_COLUMN_MSGTYPE,
308 MODEST_HEADER_VIEW_COLUMN_ATTACH,
309 MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER
312 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
314 for (i = 0 ; i != sizeof(cols) / sizeof(ModestHeaderViewColumn); ++i)
315 columns = g_slist_append (columns, GINT_TO_POINTER(cols[i]));
317 header_view = modest_widget_factory_get_header_view (priv->widget_factory);
318 modest_header_view_set_columns (header_view, columns);
319 g_slist_free (columns);
326 restore_sizes (ModestMainWindow *self)
328 ModestMainWindowPrivate *priv;
330 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
332 modest_widget_memory_restore_settings (priv->conf,GTK_WIDGET(self),
333 "modest-main-window");
334 modest_widget_memory_restore_settings (priv->conf, GTK_WIDGET(priv->folder_paned),
335 "modest-folder-paned");
336 modest_widget_memory_restore_settings (priv->conf, GTK_WIDGET(priv->msg_paned),
338 modest_widget_memory_restore_settings (priv->conf, GTK_WIDGET(priv->main_paned),
339 "modest-main-paned");
345 save_sizes (ModestMainWindow *self)
347 ModestMainWindowPrivate *priv;
349 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
351 modest_widget_memory_save_settings (priv->conf,GTK_WIDGET(self),
352 "modest-main-window");
353 modest_widget_memory_save_settings (priv->conf, GTK_WIDGET(priv->folder_paned),
354 "modest-folder-paned");
355 modest_widget_memory_save_settings (priv->conf, GTK_WIDGET(priv->msg_paned),
357 modest_widget_memory_save_settings (priv->conf, GTK_WIDGET(priv->main_paned),
358 "modest-main-paned");
366 wrapped_in_scrolled_window (GtkWidget *widget, gboolean needs_viewport)
370 win = gtk_scrolled_window_new (NULL, NULL);
371 gtk_scrolled_window_set_policy
372 (GTK_SCROLLED_WINDOW (win),GTK_POLICY_NEVER,
373 GTK_POLICY_AUTOMATIC);
376 gtk_scrolled_window_add_with_viewport
377 (GTK_SCROLLED_WINDOW(win), widget);
379 gtk_container_add (GTK_CONTAINER(win),
387 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMainWindow *self)
390 gtk_widget_destroy (GTK_WIDGET(self));
399 modest_main_window_new (ModestConf *conf, ModestAccountMgr *account_mgr,
400 ModestWidgetFactory *factory)
403 ModestMainWindowPrivate *priv;
405 GtkWidget *main_vbox;
406 GtkWidget *status_hbox;
407 GtkWidget *header_win, *folder_win;
409 g_return_val_if_fail (factory, NULL);
410 g_return_val_if_fail (conf, NULL);
412 obj = g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL);
413 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
415 g_object_ref (factory);
416 priv->widget_factory = factory;
421 g_object_ref (account_mgr);
422 priv->account_mgr = account_mgr;
425 /* widgets from factory */
426 priv->folder_view = modest_widget_factory_get_folder_view (factory);
427 priv->header_view = header_view_new (MODEST_MAIN_WINDOW(obj));
428 priv->msg_preview = modest_widget_factory_get_msg_preview (factory);
430 folder_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->folder_view),
432 header_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->header_view),
435 priv->menubar = menubar_new (MODEST_MAIN_WINDOW(obj));
436 priv->toolbar = gtk_toolbar_new ();
439 priv->folder_paned = gtk_vpaned_new ();
440 priv->msg_paned = gtk_vpaned_new ();
441 priv->main_paned = gtk_hpaned_new ();
442 gtk_paned_add1 (GTK_PANED(priv->main_paned), priv->folder_paned);
443 gtk_paned_add2 (GTK_PANED(priv->main_paned), priv->msg_paned);
444 // gtk_paned_add1 (GTK_PANED(priv->folder_paned),
445 // gtk_label_new (_("Favorites")));
446 gtk_paned_add2 (GTK_PANED(priv->folder_paned), folder_win);
447 gtk_paned_add1 (GTK_PANED(priv->msg_paned), header_win);
448 gtk_paned_add2 (GTK_PANED(priv->msg_paned), GTK_WIDGET(priv->msg_preview));
450 gtk_widget_show (GTK_WIDGET(priv->header_view));
451 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
454 /* status bar / progress */
455 status_hbox = gtk_hbox_new (FALSE, 0);
456 gtk_box_pack_start (GTK_BOX(status_hbox),
457 modest_widget_factory_get_status_bar(factory),
459 gtk_box_pack_start (GTK_BOX(status_hbox),
460 modest_widget_factory_get_progress_bar(factory),
462 gtk_box_pack_start (GTK_BOX(status_hbox),
463 modest_widget_factory_get_online_toggle(factory),
466 /* putting it all together... */
467 main_vbox = gtk_vbox_new (FALSE, 6);
468 gtk_box_pack_start (GTK_BOX(main_vbox), priv->menubar, FALSE, FALSE, 0);
469 gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, FALSE, 0);
470 gtk_box_pack_start (GTK_BOX(main_vbox), priv->main_paned, TRUE, TRUE,0);
471 gtk_box_pack_start (GTK_BOX(main_vbox), status_hbox, FALSE, FALSE, 0);
473 gtk_container_add (GTK_CONTAINER(obj), main_vbox);
474 restore_sizes (MODEST_MAIN_WINDOW(obj));
476 gtk_window_set_title (GTK_WINDOW(obj), "Modest");
477 gtk_window_set_icon (GTK_WINDOW(obj),
478 modest_icon_factory_get_icon (MODEST_APP_ICON));
480 gtk_widget_show_all (main_vbox);
482 g_signal_connect (G_OBJECT(obj), "delete-event",
483 G_CALLBACK(on_delete_event), obj);
485 return GTK_WIDGET(obj);