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 <widgets/modest-toolbar.h>
35 #include "modest-main-window.h"
36 #include "modest-account-view-window.h"
37 #include "modest-edit-msg-window.h"
38 #include "modest-icon-names.h"
41 /* 'private'/'protected' functions */
42 static void modest_main_window_class_init (ModestMainWindowClass *klass);
43 static void modest_main_window_init (ModestMainWindow *obj);
44 static void modest_main_window_finalize (GObject *obj);
46 static void restore_sizes (ModestMainWindow *self);
47 static void save_sizes (ModestMainWindow *self);
56 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
57 struct _ModestMainWindowPrivate {
62 GtkWidget *folder_paned;
64 GtkWidget *main_paned;
66 ModestWidgetFactory *factory;
68 ModestAccountMgr *account_mgr;
70 ModestHeaderView *header_view;
71 ModestFolderView *folder_view;
72 ModestMsgView *msg_preview;
76 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
77 MODEST_TYPE_MAIN_WINDOW, \
78 ModestMainWindowPrivate))
80 static GtkWindowClass *parent_class = NULL;
82 /* uncomment the following if you have defined any signals */
83 /* static guint signals[LAST_SIGNAL] = {0}; */
86 modest_main_window_get_type (void)
88 static GType my_type = 0;
90 static const GTypeInfo my_info = {
91 sizeof(ModestMainWindowClass),
93 NULL, /* base finalize */
94 (GClassInitFunc) modest_main_window_class_init,
95 NULL, /* class finalize */
96 NULL, /* class data */
97 sizeof(ModestMainWindow),
99 (GInstanceInitFunc) modest_main_window_init,
102 my_type = g_type_register_static (GTK_TYPE_WINDOW,
110 modest_main_window_class_init (ModestMainWindowClass *klass)
112 GObjectClass *gobject_class;
113 gobject_class = (GObjectClass*) klass;
115 parent_class = g_type_class_peek_parent (klass);
116 gobject_class->finalize = modest_main_window_finalize;
118 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
120 /* signal definitions go here, e.g.: */
121 /* signals[MY_SIGNAL_1] = */
122 /* g_signal_new ("my_signal_1",....); */
123 /* signals[MY_SIGNAL_2] = */
124 /* g_signal_new ("my_signal_2",....); */
129 modest_main_window_init (ModestMainWindow *obj)
131 ModestMainWindowPrivate *priv;
133 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
135 priv->factory = NULL;
137 priv->account_mgr = NULL;
141 modest_main_window_finalize (GObject *obj)
143 ModestMainWindowPrivate *priv;
144 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
146 g_object_unref (G_OBJECT(priv->factory));
147 priv->factory = NULL;
150 g_object_unref (G_OBJECT(priv->conf));
154 if (priv->account_mgr) {
155 g_object_unref (G_OBJECT(priv->account_mgr));
156 priv->account_mgr = NULL;
159 G_OBJECT_CLASS(parent_class)->finalize (obj);
164 on_menu_about (GtkWidget *widget, gpointer data)
167 const gchar *authors[] = {
168 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
171 about = gtk_about_dialog_new ();
172 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
173 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
174 gtk_about_dialog_set_copyright (
175 GTK_ABOUT_DIALOG(about),
176 _("Copyright (c) 2006, Nokia Corporation\n"
177 "All rights reserved."));
178 gtk_about_dialog_set_comments ( GTK_ABOUT_DIALOG(about),
179 _("a modest e-mail client\n\n"
180 "design and implementation: Dirk-Jan C. Binnema\n"
181 "contributions from the fine people at KernelConcepts\n\n"
182 "uses the tinymail email framework written by Philip van Hoof"));
183 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
184 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
186 gtk_dialog_run (GTK_DIALOG (about));
187 gtk_widget_destroy(about);
192 on_menu_accounts (ModestMainWindow *self, guint action, GtkWidget *widget)
194 GtkWidget *account_win;
195 ModestMainWindowPrivate *priv;
197 g_return_if_fail (widget);
198 g_return_if_fail (self);
200 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
201 account_win = modest_account_view_window_new (priv->account_mgr,
204 gtk_window_set_transient_for (GTK_WINDOW(account_win),
207 gtk_widget_show (account_win);
212 on_menu_new_message (ModestMainWindow *self, guint action, GtkWidget *widget)
215 ModestMainWindowPrivate *priv;
217 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
219 msg_win = modest_edit_msg_window_new (priv->conf,
221 MODEST_EDIT_TYPE_NEW,
223 gtk_widget_show (msg_win);
227 on_menu_quit (ModestMainWindow *self, guint action, GtkWidget *widget)
230 gtk_widget_destroy (GTK_WIDGET(self));
234 /* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
235 static GtkItemFactoryEntry menu_items[] = {
236 { "/_File", NULL, NULL, 0, "<Branch>" },
237 { "/File/_New", "<control>N", NULL, 0, "<StockItem>", GTK_STOCK_NEW },
238 { "/File/_Open", "<control>O", NULL, 0, "<StockItem>", GTK_STOCK_OPEN },
239 { "/File/_Save", "<control>S", NULL, 0, "<StockItem>", GTK_STOCK_SAVE },
240 { "/File/Save _As", NULL, NULL, 0, "<Item>" },
241 { "/File/sep1", NULL, NULL, 0, "<Separator>" },
242 { "/File/_Quit", "<CTRL>Q", on_menu_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
244 { "/_Edit", NULL, NULL, 0, "<Branch>" },
245 { "/Edit/_Undo", "<CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_UNDO },
246 { "/Edit/_Redo", "<shift><CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_REDO },
247 { "/File/sep1", NULL, NULL, 0, "<Separator>" },
248 { "/Edit/Cut", "<control>X", NULL, 0, "<StockItem>", GTK_STOCK_CUT },
249 { "/Edit/Copy", "<CTRL>C", NULL, 0, "<StockItem>", GTK_STOCK_COPY },
250 { "/Edit/Paste", NULL, NULL, 0, "<StockItem>", GTK_STOCK_PASTE},
251 { "/Edit/sep1", NULL, NULL, 0, "<Separator>" },
252 { "/Edit/Delete", "<CTRL>Q", NULL, 0, "<Item>" },
253 { "/Edit/Select all", "<CTRL>A", NULL, 0, "<Item>" },
254 { "/Edit/Deelect all", "<Shift><CTRL>A", NULL, 0, "<Item>" },
256 { "/_Actions", NULL, NULL, 0, "<Branch>" },
257 { "/Actions/_New Message", NULL, on_menu_new_message, 0, "<Item>" },
258 { "/Actions/_Reply", NULL, NULL, 0, "<Item>" },
259 { "/Actions/_Forward", NULL, NULL, 0, "<Item>" },
260 { "/Actions/_Bounce", NULL, NULL, 0, "<Item>" },
262 { "/_Options", NULL, NULL, 0, "<Branch>" },
263 { "/Options/_Accounts", NULL, on_menu_accounts,0, "<Item>" },
264 { "/Options/_Contacts", NULL, NULL, 0, "<Item>" },
267 { "/_Help", NULL, NULL, 0, "<Branch>" },
268 { "/_Help/About", NULL, on_menu_about, 0, "<StockItem>", GTK_STOCK_ABOUT},
271 static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
275 menubar_new (ModestMainWindow *self)
277 GtkItemFactory *item_factory;
278 GtkAccelGroup *accel_group;
280 /* Make an accelerator group (shortcut keys) */
281 accel_group = gtk_accel_group_new ();
283 /* Make an ItemFactory (that makes a menubar) */
284 item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
287 /* This function generates the menu items. Pass the item factory,
288 the number of items in the array, the array itself, and any
289 callback data for the the menu items. */
290 gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, self);
292 ///* Attach the new accelerator group to the window. */
293 gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
295 /* Finally, return the actual menu bar created by the item factory. */
296 return gtk_item_factory_get_widget (item_factory, "<main>");
302 static ModestHeaderView*
303 header_view_new (ModestMainWindow *self)
306 GSList *columns = NULL;
307 ModestHeaderView *header_view;
308 ModestMainWindowPrivate *priv;
309 ModestHeaderViewColumn cols[] = {
310 MODEST_HEADER_VIEW_COLUMN_MSGTYPE,
311 MODEST_HEADER_VIEW_COLUMN_ATTACH,
312 MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER
313 /* MODEST_HEADER_VIEW_COLUMN_FROM, */
314 /* MODEST_HEADER_VIEW_COLUMN_SUBJECT, */
315 /* MODEST_HEADER_VIEW_COLUMN_RECEIVED_DATE */
317 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
319 for (i = 0 ; i != sizeof(cols) / sizeof(ModestHeaderViewColumn); ++i)
320 columns = g_slist_append (columns, GINT_TO_POINTER(cols[i]));
322 header_view = modest_widget_factory_get_header_view (priv->factory);
323 modest_header_view_set_columns (header_view, columns);
324 g_slist_free (columns);
329 static ModestToolbar*
330 toolbar_new (ModestMainWindow *self)
333 ModestToolbar *toolbar;
334 GSList *buttons = NULL;
335 ModestMainWindowPrivate *priv;
337 ModestToolbarButton button_ids[] = {
338 MODEST_TOOLBAR_BUTTON_NEW_MAIL,
339 MODEST_TOOLBAR_BUTTON_REPLY,
340 MODEST_TOOLBAR_BUTTON_REPLY_ALL,
341 MODEST_TOOLBAR_BUTTON_FORWARD,
342 MODEST_TOOLBAR_SEPARATOR,
343 MODEST_TOOLBAR_BUTTON_SEND_RECEIVE,
344 MODEST_TOOLBAR_SEPARATOR,
345 MODEST_TOOLBAR_BUTTON_NEXT,
346 MODEST_TOOLBAR_BUTTON_PREV,
347 MODEST_TOOLBAR_SEPARATOR,
348 MODEST_TOOLBAR_BUTTON_DELETE
351 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
353 for (i = 0 ; i != sizeof(button_ids) / sizeof(ModestToolbarButton); ++i)
354 buttons = g_slist_append (buttons, GINT_TO_POINTER(button_ids[i]));
356 toolbar = modest_widget_factory_get_main_toolbar (priv->factory, buttons);
357 g_slist_free (buttons);
365 restore_sizes (ModestMainWindow *self)
367 ModestMainWindowPrivate *priv;
368 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
370 modest_widget_memory_restore_settings (priv->conf,GTK_WIDGET(self),
371 "modest-main-window");
372 modest_widget_memory_restore_settings (priv->conf, GTK_WIDGET(priv->folder_paned),
373 "modest-folder-paned");
374 modest_widget_memory_restore_settings (priv->conf, GTK_WIDGET(priv->msg_paned),
376 modest_widget_memory_restore_settings (priv->conf, GTK_WIDGET(priv->main_paned),
377 "modest-main-paned");
382 save_sizes (ModestMainWindow *self)
384 ModestMainWindowPrivate *priv;
386 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
388 modest_widget_memory_save_settings (priv->conf,GTK_WIDGET(self),
389 "modest-main-window");
390 modest_widget_memory_save_settings (priv->conf, GTK_WIDGET(priv->folder_paned),
391 "modest-folder-paned");
392 modest_widget_memory_save_settings (priv->conf, GTK_WIDGET(priv->msg_paned),
394 modest_widget_memory_save_settings (priv->conf, GTK_WIDGET(priv->main_paned),
395 "modest-main-paned");
399 wrapped_in_scrolled_window (GtkWidget *widget, gboolean needs_viewport)
403 win = gtk_scrolled_window_new (NULL, NULL);
404 gtk_scrolled_window_set_policy
405 (GTK_SCROLLED_WINDOW (win),GTK_POLICY_NEVER,
406 GTK_POLICY_AUTOMATIC);
409 gtk_scrolled_window_add_with_viewport
410 (GTK_SCROLLED_WINDOW(win), widget);
412 gtk_container_add (GTK_CONTAINER(win),
420 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMainWindow *self)
429 GtkWidget *favorites;
431 GtkTreeViewColumn *col;
433 store = gtk_tree_store_new (1, G_TYPE_STRING);
434 favorites = gtk_tree_view_new_with_model (GTK_TREE_MODEL(store));
435 col = gtk_tree_view_column_new_with_attributes (_("Favorites"),
436 gtk_cell_renderer_text_new(),
439 gtk_tree_view_append_column (GTK_TREE_VIEW(favorites), col);
440 gtk_widget_show_all (favorites);
442 g_object_unref (G_OBJECT(store));
450 modest_main_window_new (ModestConf *conf, ModestAccountMgr *account_mgr,
451 ModestWidgetFactory *factory)
454 ModestMainWindowPrivate *priv;
456 GtkWidget *main_vbox;
457 GtkWidget *status_hbox;
458 GtkWidget *header_win, *folder_win, *favorites_win;
460 g_return_val_if_fail (factory, NULL);
461 g_return_val_if_fail (conf, NULL);
463 obj = g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL);
464 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
466 g_object_ref (factory);
467 priv->factory = factory;
472 g_object_ref (account_mgr);
473 priv->account_mgr = account_mgr;
475 /* widgets from factory */
476 priv->folder_view = modest_widget_factory_get_folder_view (factory);
477 priv->header_view = header_view_new (MODEST_MAIN_WINDOW(obj));
478 priv->msg_preview = modest_widget_factory_get_msg_preview (factory);
480 folder_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->folder_view),
482 header_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->header_view),
484 favorites_win = wrapped_in_scrolled_window (favorites_view(),FALSE);
487 priv->menubar = menubar_new (MODEST_MAIN_WINDOW(obj));
488 priv->toolbar = GTK_WIDGET(toolbar_new (MODEST_MAIN_WINDOW(obj)));
491 priv->folder_paned = gtk_vpaned_new ();
492 priv->msg_paned = gtk_vpaned_new ();
493 priv->main_paned = gtk_hpaned_new ();
494 gtk_paned_add1 (GTK_PANED(priv->main_paned), priv->folder_paned);
495 gtk_paned_add2 (GTK_PANED(priv->main_paned), priv->msg_paned);
496 gtk_paned_add1 (GTK_PANED(priv->folder_paned), favorites_win);
497 gtk_paned_add2 (GTK_PANED(priv->folder_paned), folder_win);
498 gtk_paned_add1 (GTK_PANED(priv->msg_paned), header_win);
499 gtk_paned_add2 (GTK_PANED(priv->msg_paned), GTK_WIDGET(priv->msg_preview));
501 gtk_widget_show (GTK_WIDGET(priv->header_view));
502 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
505 /* status bar / progress */
506 status_hbox = gtk_hbox_new (FALSE, 0);
507 gtk_box_pack_start (GTK_BOX(status_hbox),
508 modest_widget_factory_get_folder_info_label (factory),
510 gtk_box_pack_start (GTK_BOX(status_hbox),
511 modest_widget_factory_get_status_bar(factory),
513 gtk_box_pack_start (GTK_BOX(status_hbox),
514 modest_widget_factory_get_progress_bar(factory),
516 gtk_box_pack_start (GTK_BOX(status_hbox),
517 modest_widget_factory_get_online_toggle(factory),
520 /* putting it all together... */
521 main_vbox = gtk_vbox_new (FALSE, 6);
522 gtk_box_pack_start (GTK_BOX(main_vbox), priv->menubar, FALSE, FALSE, 0);
523 gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, FALSE, 0);
524 gtk_box_pack_start (GTK_BOX(main_vbox), priv->main_paned, TRUE, TRUE,0);
525 gtk_box_pack_start (GTK_BOX(main_vbox), status_hbox, FALSE, FALSE, 0);
527 gtk_container_add (GTK_CONTAINER(obj), main_vbox);
528 restore_sizes (MODEST_MAIN_WINDOW(obj));
530 gtk_window_set_title (GTK_WINDOW(obj), "Modest");
531 gtk_window_set_icon (GTK_WINDOW(obj),
532 modest_icon_factory_get_icon (MODEST_APP_ICON));
534 gtk_widget_show_all (main_vbox);
536 g_signal_connect (G_OBJECT(obj), "delete-event",
537 G_CALLBACK(on_delete_event), obj);
539 return GTK_WIDGET(obj);