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;
63 ModestHeaderView *header_view;
64 ModestFolderView *folder_view;
65 ModestMsgView *msg_preview;
69 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
70 MODEST_TYPE_MAIN_WINDOW, \
71 ModestMainWindowPrivate))
73 static GtkWindowClass *parent_class = NULL;
75 /* uncomment the following if you have defined any signals */
76 /* static guint signals[LAST_SIGNAL] = {0}; */
79 modest_main_window_get_type (void)
81 static GType my_type = 0;
83 static const GTypeInfo my_info = {
84 sizeof(ModestMainWindowClass),
86 NULL, /* base finalize */
87 (GClassInitFunc) modest_main_window_class_init,
88 NULL, /* class finalize */
89 NULL, /* class data */
90 sizeof(ModestMainWindow),
92 (GInstanceInitFunc) modest_main_window_init,
94 my_type = g_type_register_static (GTK_TYPE_WINDOW,
102 modest_main_window_class_init (ModestMainWindowClass *klass)
104 GObjectClass *gobject_class;
105 gobject_class = (GObjectClass*) klass;
107 parent_class = g_type_class_peek_parent (klass);
108 gobject_class->finalize = modest_main_window_finalize;
110 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
112 /* signal definitions go here, e.g.: */
113 /* signals[MY_SIGNAL_1] = */
114 /* g_signal_new ("my_signal_1",....); */
115 /* signals[MY_SIGNAL_2] = */
116 /* g_signal_new ("my_signal_2",....); */
121 modest_main_window_init (ModestMainWindow *obj)
123 ModestMainWindowPrivate *priv;
125 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
127 priv->widget_factory = NULL;
131 modest_main_window_finalize (GObject *obj)
133 ModestMainWindowPrivate *priv;
134 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
135 if (priv->widget_factory) {
136 g_object_unref (G_OBJECT(priv->widget_factory));
137 priv->widget_factory = NULL;
140 g_object_unref (G_OBJECT(priv->conf));
143 G_OBJECT_CLASS(parent_class)->finalize (obj);
148 on_menu_about (GtkWidget *widget, gpointer data)
152 about = gtk_about_dialog_new ();
153 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
154 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
155 gtk_about_dialog_set_copyright (
156 GTK_ABOUT_DIALOG(about),
157 _("Copyright (c) 2006, Nokia Corporation\n"
158 "All rights reserved."));
159 gtk_about_dialog_set_comments ( GTK_ABOUT_DIALOG(about),
160 _("a modest e-mail client"));
161 gtk_dialog_run (GTK_DIALOG (about));
162 gtk_widget_destroy(about);
167 on_menu_accounts (ModestMainWindow *self, guint action, GtkWidget *widget)
169 GtkWidget *account_win;
170 ModestMainWindowPrivate *priv;
172 g_return_if_fail (widget);
173 g_return_if_fail (self);
175 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
176 account_win = modest_account_view_window_new (priv->conf,
177 priv->widget_factory);
179 gtk_window_set_transient_for (GTK_WINDOW(account_win),
182 gtk_widget_show (account_win);
187 on_menu_new_message (ModestMainWindow *self, guint action, GtkWidget *widget)
190 ModestMainWindowPrivate *priv;
193 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
195 msg_win = modest_edit_msg_window_new (priv->conf,
196 MODEST_EDIT_TYPE_NEW,
198 gtk_widget_show (msg_win);
202 on_menu_quit (ModestMainWindow *self, guint action, GtkWidget *widget)
209 /* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
210 static GtkItemFactoryEntry menu_items[] = {
211 { "/_File", NULL, NULL, 0, "<Branch>" },
212 { "/File/_New", "<control>N", NULL, 0, "<StockItem>", GTK_STOCK_NEW },
213 { "/File/_Open", "<control>O", NULL, 0, "<StockItem>", GTK_STOCK_OPEN },
214 { "/File/_Save", "<control>S", NULL, 0, "<StockItem>", GTK_STOCK_SAVE },
215 { "/File/Save _As", NULL, NULL, 0, "<Item>" },
216 { "/File/sep1", NULL, NULL, 0, "<Separator>" },
217 { "/File/_Quit", "<CTRL>Q", on_menu_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
219 { "/_Edit", NULL, NULL, 0, "<Branch>" },
220 { "/Edit/_Undo", "<CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_UNDO },
221 { "/Edit/_Redo", "<shift><CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_REDO },
222 { "/File/sep1", NULL, NULL, 0, "<Separator>" },
223 { "/Edit/Cut", "<control>X", NULL, 0, "<StockItem>", GTK_STOCK_CUT },
224 { "/Edit/Copy", "<CTRL>C", NULL, 0, "<StockItem>", GTK_STOCK_COPY },
225 { "/Edit/Paste", NULL, NULL, 0, "<StockItem>", GTK_STOCK_PASTE},
226 { "/Edit/sep1", NULL, NULL, 0, "<Separator>" },
227 { "/Edit/Delete", "<CTRL>Q", NULL, 0, "<Item>" },
228 { "/Edit/Select all", "<CTRL>A", NULL, 0, "<Item>" },
229 { "/Edit/Deelect all", "<Shift><CTRL>A", NULL, 0, "<Item>" },
231 { "/_Actions", NULL, NULL, 0, "<Branch>" },
232 { "/Actions/_New Message", NULL, on_menu_new_message, 0, "<Item>" },
233 { "/Actions/_Reply", NULL, NULL, 0, "<Item>" },
234 { "/Actions/_Forward", NULL, NULL, 0, "<Item>" },
235 { "/Actions/_Bounce", NULL, NULL, 0, "<Item>" },
237 { "/_Options", NULL, NULL, 0, "<Branch>" },
238 { "/Options/_Accounts", NULL, on_menu_accounts,0, "<Item>" },
239 { "/Options/_Contacts", NULL, NULL, 0, "<Item>" },
242 { "/_Help", NULL, NULL, 0, "<Branch>" },
243 { "/_Help/About", NULL, on_menu_about, 0, "<StockItem>", GTK_STOCK_ABOUT},
246 static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
250 menubar_new (ModestMainWindow *self)
252 GtkItemFactory *item_factory;
253 GtkAccelGroup *accel_group;
255 /* Make an accelerator group (shortcut keys) */
256 accel_group = gtk_accel_group_new ();
258 /* Make an ItemFactory (that makes a menubar) */
259 item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
262 /* This function generates the menu items. Pass the item factory,
263 the number of items in the array, the array itself, and any
264 callback data for the the menu items. */
265 gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, self);
267 ///* Attach the new accelerator group to the window. */
268 gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
270 /* Finally, return the actual menu bar created by the item factory. */
271 return gtk_item_factory_get_widget (item_factory, "<main>");
277 static ModestHeaderView*
278 header_view_new (ModestMainWindow *self)
281 GSList *columns = NULL;
282 ModestHeaderView *header_view;
283 ModestMainWindowPrivate *priv;
284 ModestHeaderViewColumn cols[] = {
285 MODEST_HEADER_VIEW_COLUMN_MSGTYPE,
286 MODEST_HEADER_VIEW_COLUMN_ATTACH,
287 MODEST_HEADER_VIEW_COLUMN_FROM,
288 MODEST_HEADER_VIEW_COLUMN_SUBJECT,
289 MODEST_HEADER_VIEW_COLUMN_RECEIVED_DATE
292 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
294 for (i = 0 ; i != sizeof(cols) / sizeof(ModestHeaderViewColumn); ++i)
295 columns = g_slist_append (columns, GINT_TO_POINTER(cols[i]));
297 header_view = modest_widget_factory_get_header_view (priv->widget_factory);
298 modest_header_view_set_columns (header_view, columns);
299 g_slist_free (columns);
306 restore_sizes (ModestMainWindow *self)
308 ModestMainWindowPrivate *priv;
310 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
312 modest_widget_memory_restore_settings (priv->conf,GTK_WIDGET(self),
313 "modest-main-window");
314 modest_widget_memory_restore_settings (priv->conf, GTK_WIDGET(priv->folder_paned),
315 "modest-folder-paned");
316 modest_widget_memory_restore_settings (priv->conf, GTK_WIDGET(priv->msg_paned),
318 modest_widget_memory_restore_settings (priv->conf, GTK_WIDGET(priv->main_paned),
319 "modest-main-paned");
325 save_sizes (ModestMainWindow *self)
327 ModestMainWindowPrivate *priv;
329 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
331 modest_widget_memory_save_settings (priv->conf,GTK_WIDGET(self),
332 "modest-main-window");
333 modest_widget_memory_save_settings (priv->conf, GTK_WIDGET(priv->folder_paned),
334 "modest-folder-paned");
335 modest_widget_memory_save_settings (priv->conf, GTK_WIDGET(priv->msg_paned),
337 modest_widget_memory_save_settings (priv->conf, GTK_WIDGET(priv->main_paned),
338 "modest-main-paned");
346 wrapped_in_scrolled_window (GtkWidget *widget, gboolean needs_viewport)
350 win = gtk_scrolled_window_new (NULL, NULL);
351 gtk_scrolled_window_set_policy
352 (GTK_SCROLLED_WINDOW (win),GTK_POLICY_NEVER,
353 GTK_POLICY_AUTOMATIC);
356 gtk_scrolled_window_add_with_viewport
357 (GTK_SCROLLED_WINDOW(win), widget);
359 gtk_container_add (GTK_CONTAINER(win),
367 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, 6);
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),
433 gtk_box_pack_end (GTK_BOX(status_hbox),
434 modest_widget_factory_get_online_toggle(factory),
437 /* putting it all together... */
438 main_vbox = gtk_vbox_new (FALSE, 6);
439 gtk_box_pack_start (GTK_BOX(main_vbox), priv->menubar, FALSE, FALSE, 6);
440 gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, FALSE, 6);
441 gtk_box_pack_start (GTK_BOX(main_vbox), priv->main_paned, TRUE, TRUE, 6);
442 gtk_box_pack_start (GTK_BOX(main_vbox), status_hbox, FALSE, FALSE, 6);
444 gtk_container_add (GTK_CONTAINER(obj), main_vbox);
445 restore_sizes (MODEST_MAIN_WINDOW(obj));
447 gtk_widget_show_all (main_vbox);
448 g_signal_connect (G_OBJECT(obj), "delete-event",
449 G_CALLBACK(on_delete_event), obj);
452 return GTK_WIDGET(obj);