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>
32 #include "modest-main-window.h"
33 #include "modest-account-view-window.h"
34 #include "modest-edit-msg-window.h"
36 /* 'private'/'protected' functions */
37 static void modest_main_window_class_init (ModestMainWindowClass *klass);
38 static void modest_main_window_init (ModestMainWindow *obj);
39 static void modest_main_window_finalize (GObject *obj);
41 static void restore_sizes (ModestMainWindow *self);
42 static void save_sizes (ModestMainWindow *self);
51 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
52 struct _ModestMainWindowPrivate {
57 GtkWidget *folder_paned;
59 GtkWidget *main_paned;
61 ModestWidgetFactory *widget_factory;
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,
95 my_type = g_type_register_static (GTK_TYPE_WINDOW,
103 modest_main_window_class_init (ModestMainWindowClass *klass)
105 GObjectClass *gobject_class;
106 gobject_class = (GObjectClass*) klass;
108 parent_class = g_type_class_peek_parent (klass);
109 gobject_class->finalize = modest_main_window_finalize;
111 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
113 /* signal definitions go here, e.g.: */
114 /* signals[MY_SIGNAL_1] = */
115 /* g_signal_new ("my_signal_1",....); */
116 /* signals[MY_SIGNAL_2] = */
117 /* g_signal_new ("my_signal_2",....); */
122 modest_main_window_init (ModestMainWindow *obj)
124 ModestMainWindowPrivate *priv;
126 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
128 priv->widget_factory = NULL;
132 modest_main_window_finalize (GObject *obj)
134 ModestMainWindowPrivate *priv;
135 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
136 if (priv->widget_factory) {
137 g_object_unref (G_OBJECT(priv->widget_factory));
138 priv->widget_factory = NULL;
141 g_object_unref (G_OBJECT(priv->conf));
144 G_OBJECT_CLASS(parent_class)->finalize (obj);
149 on_menu_about (GtkWidget *widget, gpointer data)
153 about = gtk_about_dialog_new ();
154 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
155 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
156 gtk_about_dialog_set_copyright (
157 GTK_ABOUT_DIALOG(about),
158 _("Copyright (c) 2006, Nokia Corporation\n"
159 "All rights reserved."));
160 gtk_about_dialog_set_comments ( GTK_ABOUT_DIALOG(about),
161 _("a modest e-mail client"));
162 gtk_dialog_run (GTK_DIALOG (about));
163 gtk_widget_destroy(about);
168 on_menu_accounts (ModestMainWindow *self, guint action, GtkWidget *widget)
170 GtkWidget *account_win;
171 ModestMainWindowPrivate *priv;
173 g_return_if_fail (widget);
174 g_return_if_fail (self);
176 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
177 account_win = modest_account_view_window_new (priv->conf,
178 priv->widget_factory);
180 gtk_window_set_transient_for (GTK_WINDOW(account_win),
183 gtk_widget_show (account_win);
188 on_menu_new_message (ModestMainWindow *self, guint action, GtkWidget *widget)
191 ModestMainWindowPrivate *priv;
194 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
196 msg_win = modest_edit_msg_window_new (priv->conf,
197 MODEST_EDIT_TYPE_NEW,
199 gtk_widget_show (msg_win);
203 on_menu_quit (ModestMainWindow *self, guint action, GtkWidget *widget)
210 /* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
211 static GtkItemFactoryEntry menu_items[] = {
212 { "/_File", NULL, NULL, 0, "<Branch>" },
213 { "/File/_New", "<control>N", NULL, 0, "<StockItem>", GTK_STOCK_NEW },
214 { "/File/_Open", "<control>O", NULL, 0, "<StockItem>", GTK_STOCK_OPEN },
215 { "/File/_Save", "<control>S", NULL, 0, "<StockItem>", GTK_STOCK_SAVE },
216 { "/File/Save _As", NULL, NULL, 0, "<Item>" },
217 { "/File/sep1", NULL, NULL, 0, "<Separator>" },
218 { "/File/_Quit", "<CTRL>Q", on_menu_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
220 { "/_Edit", NULL, NULL, 0, "<Branch>" },
221 { "/Edit/_Undo", "<CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_UNDO },
222 { "/Edit/_Redo", "<shift><CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_REDO },
223 { "/File/sep1", NULL, NULL, 0, "<Separator>" },
224 { "/Edit/Cut", "<control>X", NULL, 0, "<StockItem>", GTK_STOCK_CUT },
225 { "/Edit/Copy", "<CTRL>C", NULL, 0, "<StockItem>", GTK_STOCK_COPY },
226 { "/Edit/Paste", NULL, NULL, 0, "<StockItem>", GTK_STOCK_PASTE},
227 { "/Edit/sep1", NULL, NULL, 0, "<Separator>" },
228 { "/Edit/Delete", "<CTRL>Q", NULL, 0, "<Item>" },
229 { "/Edit/Select all", "<CTRL>A", NULL, 0, "<Item>" },
230 { "/Edit/Deelect all", "<Shift><CTRL>A", NULL, 0, "<Item>" },
232 { "/_Actions", NULL, NULL, 0, "<Branch>" },
233 { "/Actions/_New Message", NULL, on_menu_new_message, 0, "<Item>" },
234 { "/Actions/_Reply", NULL, NULL, 0, "<Item>" },
235 { "/Actions/_Forward", NULL, NULL, 0, "<Item>" },
236 { "/Actions/_Bounce", NULL, NULL, 0, "<Item>" },
238 { "/_Options", NULL, NULL, 0, "<Branch>" },
239 { "/Options/_Accounts", NULL, on_menu_accounts,0, "<Item>" },
240 { "/Options/_Contacts", NULL, NULL, 0, "<Item>" },
243 { "/_Help", NULL, NULL, 0, "<Branch>" },
244 { "/_Help/About", NULL, on_menu_about, 0, "<StockItem>", GTK_STOCK_ABOUT},
247 static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
251 menubar_new (ModestMainWindow *self)
253 GtkItemFactory *item_factory;
254 GtkAccelGroup *accel_group;
256 /* Make an accelerator group (shortcut keys) */
257 accel_group = gtk_accel_group_new ();
259 /* Make an ItemFactory (that makes a menubar) */
260 item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
263 /* This function generates the menu items. Pass the item factory,
264 the number of items in the array, the array itself, and any
265 callback data for the the menu items. */
266 gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, self);
268 ///* Attach the new accelerator group to the window. */
269 gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
271 /* Finally, return the actual menu bar created by the item factory. */
272 return gtk_item_factory_get_widget (item_factory, "<main>");
278 static ModestHeaderView*
279 header_view_new (ModestMainWindow *self)
282 GSList *columns = NULL;
283 ModestHeaderView *header_view;
284 ModestMainWindowPrivate *priv;
285 ModestHeaderViewColumn cols[] = {
286 MODEST_HEADER_VIEW_COLUMN_MSGTYPE,
287 MODEST_HEADER_VIEW_COLUMN_ATTACH,
288 MODEST_HEADER_VIEW_COLUMN_FROM,
289 MODEST_HEADER_VIEW_COLUMN_SUBJECT,
290 MODEST_HEADER_VIEW_COLUMN_RECEIVED_DATE
293 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
295 for (i = 0 ; i != sizeof(cols) / sizeof(ModestHeaderViewColumn); ++i)
296 columns = g_slist_append (columns, GINT_TO_POINTER(cols[i]));
298 header_view = modest_widget_factory_get_header_view (priv->widget_factory);
299 modest_header_view_set_columns (header_view, columns);
300 g_slist_free (columns);
307 restore_sizes (ModestMainWindow *self)
309 ModestMainWindowPrivate *priv;
311 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
313 modest_widget_memory_restore_settings (priv->conf,GTK_WIDGET(self),
314 "modest-main-window");
315 modest_widget_memory_restore_settings (priv->conf, GTK_WIDGET(priv->folder_paned),
316 "modest-folder-paned");
317 modest_widget_memory_restore_settings (priv->conf, GTK_WIDGET(priv->msg_paned),
319 modest_widget_memory_restore_settings (priv->conf, GTK_WIDGET(priv->main_paned),
320 "modest-main-paned");
326 save_sizes (ModestMainWindow *self)
328 ModestMainWindowPrivate *priv;
330 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
332 modest_widget_memory_save_settings (priv->conf,GTK_WIDGET(self),
333 "modest-main-window");
334 modest_widget_memory_save_settings (priv->conf, GTK_WIDGET(priv->folder_paned),
335 "modest-folder-paned");
336 modest_widget_memory_save_settings (priv->conf, GTK_WIDGET(priv->msg_paned),
338 modest_widget_memory_save_settings (priv->conf, GTK_WIDGET(priv->main_paned),
339 "modest-main-paned");
347 wrapped_in_scrolled_window (GtkWidget *widget, gboolean needs_viewport)
351 win = gtk_scrolled_window_new (NULL, NULL);
352 gtk_scrolled_window_set_policy
353 (GTK_SCROLLED_WINDOW (win),GTK_POLICY_NEVER,
354 GTK_POLICY_AUTOMATIC);
357 gtk_scrolled_window_add_with_viewport
358 (GTK_SCROLLED_WINDOW(win), widget);
360 gtk_container_add (GTK_CONTAINER(win),
368 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMainWindow *self)
377 modest_main_window_new (ModestWidgetFactory *factory, ModestConf *conf)
380 ModestMainWindowPrivate *priv;
382 GtkWidget *main_vbox;
383 GtkWidget *status_hbox;
384 GtkWidget *header_win, *folder_win;
386 g_return_val_if_fail (factory, NULL);
387 g_return_val_if_fail (conf, NULL);
389 obj = g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL);
390 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
392 g_object_ref (factory);
393 priv->widget_factory = factory;
398 /* widgets from factory */
399 priv->folder_view = modest_widget_factory_get_folder_view (factory);
400 priv->header_view = header_view_new (MODEST_MAIN_WINDOW(obj));
401 priv->msg_preview = modest_widget_factory_get_msg_preview (factory);
403 folder_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->folder_view),
405 header_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->header_view),
408 priv->menubar = menubar_new (MODEST_MAIN_WINDOW(obj));
409 priv->toolbar = gtk_toolbar_new ();
412 priv->folder_paned = gtk_vpaned_new ();
413 priv->msg_paned = gtk_vpaned_new ();
414 priv->main_paned = gtk_hpaned_new ();
415 gtk_paned_add1 (GTK_PANED(priv->main_paned), priv->folder_paned);
416 gtk_paned_add2 (GTK_PANED(priv->main_paned), priv->msg_paned);
417 gtk_paned_add1 (GTK_PANED(priv->folder_paned),
418 gtk_label_new (_("Favorites")));
419 gtk_paned_add2 (GTK_PANED(priv->folder_paned), folder_win);
420 gtk_paned_add1 (GTK_PANED(priv->msg_paned), header_win);
421 gtk_paned_add2 (GTK_PANED(priv->msg_paned), GTK_WIDGET(priv->msg_preview));
423 gtk_widget_show (GTK_WIDGET(priv->header_view));
425 /* status bar / progress */
426 status_hbox = gtk_hbox_new (TRUE, 5);
427 gtk_box_pack_start (GTK_BOX(status_hbox),
428 modest_widget_factory_get_status_bar(factory),
430 gtk_box_pack_start (GTK_BOX(status_hbox),
431 modest_widget_factory_get_progress_bar(factory),
434 /* putting it all together... */
435 main_vbox = gtk_vbox_new (FALSE, 2);
436 gtk_box_pack_start (GTK_BOX(main_vbox), priv->menubar, FALSE, FALSE, 2);
437 gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, TRUE, 5);
438 gtk_box_pack_start (GTK_BOX(main_vbox), priv->main_paned, TRUE, TRUE, 2);
439 gtk_box_pack_start (GTK_BOX(main_vbox), status_hbox, FALSE, FALSE, 5);
441 gtk_container_add (GTK_CONTAINER(obj), main_vbox);
442 gtk_widget_show_all (main_vbox);
444 gtk_window_set_title (GTK_WINDOW(obj), "Modest");
446 g_signal_connect (G_OBJECT(obj), "delete-event",
447 G_CALLBACK(on_delete_event), obj);
449 restore_sizes (MODEST_MAIN_WINDOW(obj));
451 return GTK_WIDGET(obj);