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-main-window.h"
32 #include "modest-account-view-window.h"
33 #include "modest-edit-msg-window.h"
35 /* 'private'/'protected' functions */
36 static void modest_main_window_class_init (ModestMainWindowClass *klass);
37 static void modest_main_window_init (ModestMainWindow *obj);
38 static void modest_main_window_finalize (GObject *obj);
40 static void restore_sizes (ModestMainWindow *self);
41 static void save_sizes (ModestMainWindow *self);
50 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
51 struct _ModestMainWindowPrivate {
56 GtkWidget *folder_paned;
58 GtkWidget *main_paned;
60 ModestWidgetFactory *widget_factory;
62 ModestAccountMgr *account_mgr;
64 ModestHeaderView *header_view;
65 ModestFolderView *folder_view;
66 ModestMsgView *msg_preview;
70 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
71 MODEST_TYPE_MAIN_WINDOW, \
72 ModestMainWindowPrivate))
74 static GtkWindowClass *parent_class = NULL;
76 /* uncomment the following if you have defined any signals */
77 /* static guint signals[LAST_SIGNAL] = {0}; */
80 modest_main_window_get_type (void)
82 static GType my_type = 0;
84 static const GTypeInfo my_info = {
85 sizeof(ModestMainWindowClass),
87 NULL, /* base finalize */
88 (GClassInitFunc) modest_main_window_class_init,
89 NULL, /* class finalize */
90 NULL, /* class data */
91 sizeof(ModestMainWindow),
93 (GInstanceInitFunc) modest_main_window_init,
96 my_type = g_type_register_static (GTK_TYPE_WINDOW,
104 modest_main_window_class_init (ModestMainWindowClass *klass)
106 GObjectClass *gobject_class;
107 gobject_class = (GObjectClass*) klass;
109 parent_class = g_type_class_peek_parent (klass);
110 gobject_class->finalize = modest_main_window_finalize;
112 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
114 /* signal definitions go here, e.g.: */
115 /* signals[MY_SIGNAL_1] = */
116 /* g_signal_new ("my_signal_1",....); */
117 /* signals[MY_SIGNAL_2] = */
118 /* g_signal_new ("my_signal_2",....); */
123 modest_main_window_init (ModestMainWindow *obj)
125 ModestMainWindowPrivate *priv;
127 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
129 priv->widget_factory = NULL;
131 priv->account_mgr = NULL;
135 modest_main_window_finalize (GObject *obj)
137 ModestMainWindowPrivate *priv;
138 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
139 if (priv->widget_factory) {
140 g_object_unref (G_OBJECT(priv->widget_factory));
141 priv->widget_factory = NULL;
144 g_object_unref (G_OBJECT(priv->conf));
148 if (priv->account_mgr) {
149 g_object_unref (G_OBJECT(priv->account_mgr));
150 priv->account_mgr = NULL;
153 G_OBJECT_CLASS(parent_class)->finalize (obj);
158 on_menu_about (GtkWidget *widget, gpointer data)
161 const gchar *authors[] = {
162 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
165 about = gtk_about_dialog_new ();
166 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
167 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
168 gtk_about_dialog_set_copyright (
169 GTK_ABOUT_DIALOG(about),
170 _("Copyright (c) 2006, Nokia Corporation\n"
171 "All rights reserved."));
172 gtk_about_dialog_set_comments ( GTK_ABOUT_DIALOG(about),
173 _("a modest e-mail client\n\n"
174 "design and implementation: Dirk-Jan C. Binnema\n"
175 "contributions from the fine people at KernelConcepts\n\n"
176 "uses the tinymail email framework written by Philip van Hoof"));
177 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
178 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
180 gtk_dialog_run (GTK_DIALOG (about));
181 gtk_widget_destroy(about);
186 on_menu_accounts (ModestMainWindow *self, guint action, GtkWidget *widget)
188 GtkWidget *account_win;
189 ModestMainWindowPrivate *priv;
191 g_return_if_fail (widget);
192 g_return_if_fail (self);
194 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
195 account_win = modest_account_view_window_new (priv->account_mgr,
196 priv->widget_factory);
198 gtk_window_set_transient_for (GTK_WINDOW(account_win),
201 gtk_widget_show (account_win);
206 on_menu_new_message (ModestMainWindow *self, guint action, GtkWidget *widget)
209 ModestMainWindowPrivate *priv;
211 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
213 msg_win = modest_edit_msg_window_new (priv->conf,
214 MODEST_EDIT_TYPE_NEW,
216 gtk_widget_show (msg_win);
220 on_menu_quit (ModestMainWindow *self, guint action, GtkWidget *widget)
227 /* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
228 static GtkItemFactoryEntry menu_items[] = {
229 { "/_File", NULL, NULL, 0, "<Branch>" },
230 { "/File/_New", "<control>N", NULL, 0, "<StockItem>", GTK_STOCK_NEW },
231 { "/File/_Open", "<control>O", NULL, 0, "<StockItem>", GTK_STOCK_OPEN },
232 { "/File/_Save", "<control>S", NULL, 0, "<StockItem>", GTK_STOCK_SAVE },
233 { "/File/Save _As", NULL, NULL, 0, "<Item>" },
234 { "/File/sep1", NULL, NULL, 0, "<Separator>" },
235 { "/File/_Quit", "<CTRL>Q", on_menu_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
237 { "/_Edit", NULL, NULL, 0, "<Branch>" },
238 { "/Edit/_Undo", "<CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_UNDO },
239 { "/Edit/_Redo", "<shift><CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_REDO },
240 { "/File/sep1", NULL, NULL, 0, "<Separator>" },
241 { "/Edit/Cut", "<control>X", NULL, 0, "<StockItem>", GTK_STOCK_CUT },
242 { "/Edit/Copy", "<CTRL>C", NULL, 0, "<StockItem>", GTK_STOCK_COPY },
243 { "/Edit/Paste", NULL, NULL, 0, "<StockItem>", GTK_STOCK_PASTE},
244 { "/Edit/sep1", NULL, NULL, 0, "<Separator>" },
245 { "/Edit/Delete", "<CTRL>Q", NULL, 0, "<Item>" },
246 { "/Edit/Select all", "<CTRL>A", NULL, 0, "<Item>" },
247 { "/Edit/Deelect all", "<Shift><CTRL>A", NULL, 0, "<Item>" },
249 { "/_Actions", NULL, NULL, 0, "<Branch>" },
250 { "/Actions/_New Message", NULL, on_menu_new_message, 0, "<Item>" },
251 { "/Actions/_Reply", NULL, NULL, 0, "<Item>" },
252 { "/Actions/_Forward", NULL, NULL, 0, "<Item>" },
253 { "/Actions/_Bounce", NULL, NULL, 0, "<Item>" },
255 { "/_Options", NULL, NULL, 0, "<Branch>" },
256 { "/Options/_Accounts", NULL, on_menu_accounts,0, "<Item>" },
257 { "/Options/_Contacts", NULL, NULL, 0, "<Item>" },
260 { "/_Help", NULL, NULL, 0, "<Branch>" },
261 { "/_Help/About", NULL, on_menu_about, 0, "<StockItem>", GTK_STOCK_ABOUT},
264 static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
268 menubar_new (ModestMainWindow *self)
270 GtkItemFactory *item_factory;
271 GtkAccelGroup *accel_group;
273 /* Make an accelerator group (shortcut keys) */
274 accel_group = gtk_accel_group_new ();
276 /* Make an ItemFactory (that makes a menubar) */
277 item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
280 /* This function generates the menu items. Pass the item factory,
281 the number of items in the array, the array itself, and any
282 callback data for the the menu items. */
283 gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, self);
285 ///* Attach the new accelerator group to the window. */
286 gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
288 /* Finally, return the actual menu bar created by the item factory. */
289 return gtk_item_factory_get_widget (item_factory, "<main>");
295 static ModestHeaderView*
296 header_view_new (ModestMainWindow *self)
299 GSList *columns = NULL;
300 ModestHeaderView *header_view;
301 ModestMainWindowPrivate *priv;
302 ModestHeaderViewColumn cols[] = {
303 MODEST_HEADER_VIEW_COLUMN_MSGTYPE,
304 MODEST_HEADER_VIEW_COLUMN_ATTACH,
305 MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER
308 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
310 for (i = 0 ; i != sizeof(cols) / sizeof(ModestHeaderViewColumn); ++i)
311 columns = g_slist_append (columns, GINT_TO_POINTER(cols[i]));
313 header_view = modest_widget_factory_get_header_view (priv->widget_factory);
314 modest_header_view_set_columns (header_view, columns);
315 g_slist_free (columns);
322 restore_sizes (ModestMainWindow *self)
324 ModestMainWindowPrivate *priv;
326 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
328 modest_widget_memory_restore_settings (priv->conf,GTK_WIDGET(self),
329 "modest-main-window");
330 modest_widget_memory_restore_settings (priv->conf, GTK_WIDGET(priv->folder_paned),
331 "modest-folder-paned");
332 modest_widget_memory_restore_settings (priv->conf, GTK_WIDGET(priv->msg_paned),
334 modest_widget_memory_restore_settings (priv->conf, GTK_WIDGET(priv->main_paned),
335 "modest-main-paned");
341 save_sizes (ModestMainWindow *self)
343 ModestMainWindowPrivate *priv;
345 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
347 modest_widget_memory_save_settings (priv->conf,GTK_WIDGET(self),
348 "modest-main-window");
349 modest_widget_memory_save_settings (priv->conf, GTK_WIDGET(priv->folder_paned),
350 "modest-folder-paned");
351 modest_widget_memory_save_settings (priv->conf, GTK_WIDGET(priv->msg_paned),
353 modest_widget_memory_save_settings (priv->conf, GTK_WIDGET(priv->main_paned),
354 "modest-main-paned");
362 wrapped_in_scrolled_window (GtkWidget *widget, gboolean needs_viewport)
366 win = gtk_scrolled_window_new (NULL, NULL);
367 gtk_scrolled_window_set_policy
368 (GTK_SCROLLED_WINDOW (win),GTK_POLICY_NEVER,
369 GTK_POLICY_AUTOMATIC);
372 gtk_scrolled_window_add_with_viewport
373 (GTK_SCROLLED_WINDOW(win), widget);
375 gtk_container_add (GTK_CONTAINER(win),
383 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMainWindow *self)
386 gtk_widget_destroy (GTK_WIDGET(self));
395 modest_main_window_new (ModestConf *conf, ModestAccountMgr *account_mgr,
396 ModestWidgetFactory *factory)
399 ModestMainWindowPrivate *priv;
401 GtkWidget *main_vbox;
402 GtkWidget *status_hbox;
403 GtkWidget *header_win, *folder_win;
405 g_return_val_if_fail (factory, NULL);
406 g_return_val_if_fail (conf, NULL);
408 obj = g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL);
409 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
411 g_object_ref (factory);
412 priv->widget_factory = factory;
417 g_object_ref (account_mgr);
418 priv->account_mgr = account_mgr;
421 /* widgets from factory */
422 priv->folder_view = modest_widget_factory_get_folder_view (factory);
423 priv->header_view = header_view_new (MODEST_MAIN_WINDOW(obj));
424 priv->msg_preview = modest_widget_factory_get_msg_preview (factory);
426 folder_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->folder_view),
428 header_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->header_view),
431 priv->menubar = menubar_new (MODEST_MAIN_WINDOW(obj));
432 priv->toolbar = gtk_toolbar_new ();
435 priv->folder_paned = gtk_vpaned_new ();
436 priv->msg_paned = gtk_vpaned_new ();
437 priv->main_paned = gtk_hpaned_new ();
438 gtk_paned_add1 (GTK_PANED(priv->main_paned), priv->folder_paned);
439 gtk_paned_add2 (GTK_PANED(priv->main_paned), priv->msg_paned);
440 // gtk_paned_add1 (GTK_PANED(priv->folder_paned),
441 // gtk_label_new (_("Favorites")));
442 gtk_paned_add2 (GTK_PANED(priv->folder_paned), folder_win);
443 gtk_paned_add1 (GTK_PANED(priv->msg_paned), header_win);
444 gtk_paned_add2 (GTK_PANED(priv->msg_paned), GTK_WIDGET(priv->msg_preview));
446 gtk_widget_show (GTK_WIDGET(priv->header_view));
447 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
450 /* status bar / progress */
451 status_hbox = gtk_hbox_new (FALSE, 0);
452 gtk_box_pack_start (GTK_BOX(status_hbox),
453 modest_widget_factory_get_status_bar(factory),
455 gtk_box_pack_start (GTK_BOX(status_hbox),
456 modest_widget_factory_get_progress_bar(factory),
458 gtk_box_pack_start (GTK_BOX(status_hbox),
459 modest_widget_factory_get_online_toggle(factory),
462 /* putting it all together... */
463 main_vbox = gtk_vbox_new (FALSE, 6);
464 gtk_box_pack_start (GTK_BOX(main_vbox), priv->menubar, FALSE, FALSE, 0);
465 gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, FALSE, 0);
466 gtk_box_pack_start (GTK_BOX(main_vbox), priv->main_paned, TRUE, TRUE,0);
467 gtk_box_pack_start (GTK_BOX(main_vbox), status_hbox, FALSE, FALSE, 0);
469 gtk_container_add (GTK_CONTAINER(obj), main_vbox);
470 restore_sizes (MODEST_MAIN_WINDOW(obj));
472 gtk_window_set_title (GTK_WINDOW(obj), "Modest");
474 gtk_widget_show_all (main_vbox);
476 g_signal_connect (G_OBJECT(obj), "delete-event",
477 G_CALLBACK(on_delete_event), obj);
479 return GTK_WIDGET(obj);