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-account-mgr.h"
38 #include "modest-conf.h"
39 #include "modest-edit-msg-window.h"
40 #include "modest-icon-names.h"
41 #include "modest-tny-platform-factory.h"
43 /* 'private'/'protected' functions */
44 static void modest_main_window_class_init (ModestMainWindowClass *klass);
45 static void modest_main_window_init (ModestMainWindow *obj);
46 static void modest_main_window_finalize (GObject *obj);
48 static void restore_sizes (ModestMainWindow *self);
49 static void save_sizes (ModestMainWindow *self);
58 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
59 struct _ModestMainWindowPrivate {
64 GtkWidget *folder_paned;
66 GtkWidget *main_paned;
68 ModestWidgetFactory *widget_factory;
69 TnyPlatformFactory *factory;
71 ModestHeaderView *header_view;
72 ModestFolderView *folder_view;
73 ModestMsgView *msg_preview;
77 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
78 MODEST_TYPE_MAIN_WINDOW, \
79 ModestMainWindowPrivate))
81 static GtkWindowClass *parent_class = NULL;
83 /* uncomment the following if you have defined any signals */
84 /* static guint signals[LAST_SIGNAL] = {0}; */
87 modest_main_window_get_type (void)
89 static GType my_type = 0;
91 static const GTypeInfo my_info = {
92 sizeof(ModestMainWindowClass),
94 NULL, /* base finalize */
95 (GClassInitFunc) modest_main_window_class_init,
96 NULL, /* class finalize */
97 NULL, /* class data */
98 sizeof(ModestMainWindow),
100 (GInstanceInitFunc) modest_main_window_init,
103 my_type = g_type_register_static (GTK_TYPE_WINDOW,
111 modest_main_window_class_init (ModestMainWindowClass *klass)
113 GObjectClass *gobject_class;
114 gobject_class = (GObjectClass*) klass;
116 parent_class = g_type_class_peek_parent (klass);
117 gobject_class->finalize = modest_main_window_finalize;
119 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
121 /* signal definitions go here, e.g.: */
122 /* signals[MY_SIGNAL_1] = */
123 /* g_signal_new ("my_signal_1",....); */
124 /* signals[MY_SIGNAL_2] = */
125 /* g_signal_new ("my_signal_2",....); */
130 modest_main_window_init (ModestMainWindow *obj)
132 ModestMainWindowPrivate *priv;
134 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
136 priv->factory = modest_tny_platform_factory_get_instance ();
140 modest_main_window_finalize (GObject *obj)
142 ModestMainWindowPrivate *priv;
143 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
144 if (priv->widget_factory) {
145 g_object_unref (G_OBJECT(priv->widget_factory));
146 priv->widget_factory = NULL;
149 G_OBJECT_CLASS(parent_class)->finalize (obj);
154 on_menu_about (GtkWidget *widget, gpointer data)
157 const gchar *authors[] = {
158 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
161 about = gtk_about_dialog_new ();
162 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
163 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
164 gtk_about_dialog_set_copyright (
165 GTK_ABOUT_DIALOG(about),
166 _("Copyright (c) 2006, Nokia Corporation\n"
167 "All rights reserved."));
168 gtk_about_dialog_set_comments ( GTK_ABOUT_DIALOG(about),
169 _("a modest e-mail client\n\n"
170 "design and implementation: Dirk-Jan C. Binnema\n"
171 "contributions from the fine people at KernelConcepts\n\n"
172 "uses the tinymail email framework written by Philip van Hoof"));
173 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
174 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
176 gtk_dialog_run (GTK_DIALOG (about));
177 gtk_widget_destroy(about);
182 on_menu_accounts (ModestMainWindow *self, guint action, GtkWidget *widget)
184 GtkWidget *account_win;
185 ModestMainWindowPrivate *priv;
187 g_return_if_fail (widget);
188 g_return_if_fail (self);
190 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
191 account_win = modest_account_view_window_new (priv->widget_factory);
193 gtk_window_set_transient_for (GTK_WINDOW(account_win),
196 gtk_widget_show (account_win);
201 on_menu_new_message (ModestMainWindow *self, guint action, GtkWidget *widget)
204 ModestMainWindowPrivate *priv;
206 TnyAccountStore *account_store;
208 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
209 conf = modest_tny_platform_factory_get_modest_conf_instance (priv->factory);
210 account_store = tny_platform_factory_new_account_store (priv->factory);
212 msg_win = modest_edit_msg_window_new (priv->widget_factory,
213 MODEST_EDIT_TYPE_NEW,
215 gtk_widget_show (msg_win);
219 on_menu_quit (ModestMainWindow *self, guint action, GtkWidget *widget)
222 gtk_widget_destroy (GTK_WIDGET(self));
226 /* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
227 static GtkItemFactoryEntry menu_items[] = {
228 { "/_File", NULL, NULL, 0, "<Branch>", NULL },
229 { "/File/_New", "<control>N", NULL, 0, "<StockItem>", GTK_STOCK_NEW },
230 { "/File/_Open", "<control>O", NULL, 0, "<StockItem>", GTK_STOCK_OPEN },
231 { "/File/_Save", "<control>S", NULL, 0, "<StockItem>", GTK_STOCK_SAVE },
232 { "/File/Save _As", NULL, NULL, 0, "<Item>", NULL },
233 { "/File/sep1", NULL, NULL, 0, "<Separator>", NULL },
234 { "/File/_Quit", "<CTRL>Q", on_menu_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
236 { "/_Edit", NULL, NULL, 0, "<Branch>", NULL },
237 { "/Edit/_Undo", "<CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_UNDO },
238 { "/Edit/_Redo", "<shift><CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_REDO },
239 { "/File/sep1", NULL, NULL, 0, "<Separator>", NULL },
240 { "/Edit/Cut", "<control>X", NULL, 0, "<StockItem>", GTK_STOCK_CUT },
241 { "/Edit/Copy", "<CTRL>C", NULL, 0, "<StockItem>", GTK_STOCK_COPY },
242 { "/Edit/Paste", NULL, NULL, 0, "<StockItem>", GTK_STOCK_PASTE},
243 { "/Edit/sep1", NULL, NULL, 0, "<Separator>", NULL },
244 { "/Edit/Delete", "<CTRL>Q", NULL, 0, "<Item>" ,NULL},
245 { "/Edit/Select all", "<CTRL>A", NULL, 0, "<Item>" ,NULL},
246 { "/Edit/Deelect all", "<Shift><CTRL>A", NULL, 0, "<Item>" ,NULL},
248 { "/_Actions", NULL, NULL, 0, "<Branch>" ,NULL},
249 { "/Actions/_New Message", NULL, on_menu_new_message, 0, "<Item>",NULL },
250 { "/Actions/_Reply", NULL, NULL, 0, "<Item>" ,NULL},
251 { "/Actions/_Forward", NULL, NULL, 0, "<Item>" ,NULL},
252 { "/Actions/_Bounce", NULL, NULL, 0, "<Item>",NULL },
254 { "/_Options", NULL, NULL, 0, "<Branch>" ,NULL},
255 { "/Options/_Accounts", NULL, on_menu_accounts,0, "<Item>" ,NULL},
256 { "/Options/_Contacts", NULL, NULL, 0, "<Item>" ,NULL },
259 { "/_Help", NULL, NULL, 0, "<Branch>" ,NULL},
260 { "/_Help/About", NULL, on_menu_about, 0, "<StockItem>", GTK_STOCK_ABOUT},
263 static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
267 menubar_new (ModestMainWindow *self)
269 GtkItemFactory *item_factory;
270 GtkAccelGroup *accel_group;
272 /* Make an accelerator group (shortcut keys) */
273 accel_group = gtk_accel_group_new ();
275 /* Make an ItemFactory (that makes a menubar) */
276 item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
279 /* This function generates the menu items. Pass the item factory,
280 the number of items in the array, the array itself, and any
281 callback data for the the menu items. */
282 gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, self);
284 ///* Attach the new accelerator group to the window. */
285 gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
287 /* Finally, return the actual menu bar created by the item factory. */
288 return gtk_item_factory_get_widget (item_factory, "<main>");
294 static ModestHeaderView*
295 header_view_new (ModestMainWindow *self)
298 GSList *columns = NULL;
299 ModestHeaderView *header_view;
300 ModestMainWindowPrivate *priv;
301 ModestHeaderViewColumn cols[] = {
302 MODEST_HEADER_VIEW_COLUMN_MSGTYPE,
303 MODEST_HEADER_VIEW_COLUMN_ATTACH,
304 MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER
305 /* MODEST_HEADER_VIEW_COLUMN_FROM, */
306 /* MODEST_HEADER_VIEW_COLUMN_SUBJECT, */
307 /* MODEST_HEADER_VIEW_COLUMN_RECEIVED_DATE */
309 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
311 for (i = 0 ; i != sizeof(cols) / sizeof(ModestHeaderViewColumn); ++i)
312 columns = g_slist_append (columns, GINT_TO_POINTER(cols[i]));
314 header_view = modest_widget_factory_get_header_view (priv->widget_factory);
315 modest_header_view_set_columns (header_view, columns);
316 g_slist_free (columns);
322 on_toolbar_button_clicked (ModestToolbar *toolbar, ModestToolbarButton button_id,
323 ModestMainWindow *self)
325 GtkTreeSelection *sel;
328 ModestMainWindowPrivate *priv;
330 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
333 case MODEST_TOOLBAR_BUTTON_NEW_MAIL:
334 on_menu_new_message (self, 0, NULL);
336 case MODEST_TOOLBAR_BUTTON_REPLY:
338 case MODEST_TOOLBAR_BUTTON_REPLY_ALL:
340 case MODEST_TOOLBAR_BUTTON_FORWARD:
342 case MODEST_TOOLBAR_BUTTON_SEND_RECEIVE:
345 case MODEST_TOOLBAR_BUTTON_NEXT:
346 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(priv->header_view));
348 gtk_tree_selection_get_selected (sel, &model, &iter);
349 gtk_tree_model_iter_next (model, &iter);
350 gtk_tree_selection_select_iter (sel, &iter);
353 case MODEST_TOOLBAR_BUTTON_PREV:
355 /* gtk_tree_selection_get_selected (sel, &model, &iter); */
356 /* gtk_tree_model_iter_prev (model, &iter); */
357 /* gtk_tree_selection_select_iter (sel, &iter); */
361 case MODEST_TOOLBAR_BUTTON_DELETE:
364 g_printerr ("modest: key %d pressed\n", button_id);
368 static ModestToolbar*
369 toolbar_new (ModestMainWindow *self)
372 ModestToolbar *toolbar;
373 GSList *buttons = NULL;
374 ModestMainWindowPrivate *priv;
376 ModestToolbarButton button_ids[] = {
377 MODEST_TOOLBAR_BUTTON_NEW_MAIL,
378 MODEST_TOOLBAR_BUTTON_REPLY,
379 MODEST_TOOLBAR_BUTTON_REPLY_ALL,
380 MODEST_TOOLBAR_BUTTON_FORWARD,
381 MODEST_TOOLBAR_SEPARATOR,
382 MODEST_TOOLBAR_BUTTON_SEND_RECEIVE,
383 MODEST_TOOLBAR_SEPARATOR,
384 MODEST_TOOLBAR_BUTTON_PREV,
385 MODEST_TOOLBAR_BUTTON_NEXT,
386 MODEST_TOOLBAR_SEPARATOR,
387 MODEST_TOOLBAR_BUTTON_DELETE
390 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
392 for (i = 0 ; i != sizeof(button_ids) / sizeof(ModestToolbarButton); ++i)
393 buttons = g_slist_append (buttons, GINT_TO_POINTER(button_ids[i]));
395 toolbar = modest_widget_factory_get_main_toolbar (priv->widget_factory, buttons);
396 g_slist_free (buttons);
398 g_signal_connect (G_OBJECT(toolbar), "button_clicked",
399 G_CALLBACK(on_toolbar_button_clicked), self);
407 restore_sizes (ModestMainWindow *self)
410 ModestMainWindowPrivate *priv;
412 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
413 conf = modest_tny_platform_factory_get_modest_conf_instance (priv->factory);
415 modest_widget_memory_restore_settings (conf,GTK_WIDGET(self),
416 "modest-main-window");
417 modest_widget_memory_restore_settings (conf, GTK_WIDGET(priv->folder_paned),
418 "modest-folder-paned");
419 modest_widget_memory_restore_settings (conf, GTK_WIDGET(priv->msg_paned),
421 modest_widget_memory_restore_settings (conf, GTK_WIDGET(priv->main_paned),
422 "modest-main-paned");
427 save_sizes (ModestMainWindow *self)
429 ModestMainWindowPrivate *priv;
432 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
433 conf = modest_tny_platform_factory_get_modest_conf_instance (priv->factory);
435 modest_widget_memory_save_settings (conf,GTK_WIDGET(self),
436 "modest-main-window");
437 modest_widget_memory_save_settings (conf, GTK_WIDGET(priv->folder_paned),
438 "modest-folder-paned");
439 modest_widget_memory_save_settings (conf, GTK_WIDGET(priv->msg_paned),
441 modest_widget_memory_save_settings (conf, GTK_WIDGET(priv->main_paned),
442 "modest-main-paned");
446 wrapped_in_scrolled_window (GtkWidget *widget, gboolean needs_viewport)
450 win = gtk_scrolled_window_new (NULL, NULL);
451 gtk_scrolled_window_set_policy
452 (GTK_SCROLLED_WINDOW (win),GTK_POLICY_NEVER,
453 GTK_POLICY_AUTOMATIC);
456 gtk_scrolled_window_add_with_viewport
457 (GTK_SCROLLED_WINDOW(win), widget);
459 gtk_container_add (GTK_CONTAINER(win),
467 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMainWindow *self)
476 GtkWidget *favorites;
478 GtkTreeViewColumn *col;
480 store = gtk_tree_store_new (1, G_TYPE_STRING);
481 favorites = gtk_tree_view_new_with_model (GTK_TREE_MODEL(store));
482 col = gtk_tree_view_column_new_with_attributes (_("Favorites"),
483 gtk_cell_renderer_text_new(),
486 gtk_tree_view_append_column (GTK_TREE_VIEW(favorites), col);
487 gtk_widget_show_all (favorites);
489 g_object_unref (G_OBJECT(store));
497 modest_main_window_new (ModestWidgetFactory *widget_factory)
500 ModestMainWindowPrivate *priv;
502 GtkWidget *main_vbox;
503 GtkWidget *status_hbox;
504 GtkWidget *header_win, *folder_win, *favorites_win;
506 g_return_val_if_fail (widget_factory, NULL);
508 obj = g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL);
509 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
511 g_object_ref (widget_factory);
512 priv->widget_factory = widget_factory;
514 /* widgets from factory */
515 priv->folder_view = modest_widget_factory_get_folder_view (widget_factory);
516 priv->header_view = header_view_new (MODEST_MAIN_WINDOW(obj));
517 priv->msg_preview = modest_widget_factory_get_msg_preview (widget_factory);
519 folder_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->folder_view),
521 header_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->header_view),
523 favorites_win = wrapped_in_scrolled_window (favorites_view(),FALSE);
526 priv->menubar = menubar_new (MODEST_MAIN_WINDOW(obj));
527 priv->toolbar = GTK_WIDGET(toolbar_new (MODEST_MAIN_WINDOW(obj)));
530 priv->folder_paned = gtk_vpaned_new ();
531 priv->msg_paned = gtk_vpaned_new ();
532 priv->main_paned = gtk_hpaned_new ();
533 gtk_paned_add1 (GTK_PANED(priv->main_paned), priv->folder_paned);
534 gtk_paned_add2 (GTK_PANED(priv->main_paned), priv->msg_paned);
535 gtk_paned_add1 (GTK_PANED(priv->folder_paned), favorites_win);
536 gtk_paned_add2 (GTK_PANED(priv->folder_paned), folder_win);
537 gtk_paned_add1 (GTK_PANED(priv->msg_paned), header_win);
538 gtk_paned_add2 (GTK_PANED(priv->msg_paned), GTK_WIDGET(priv->msg_preview));
540 gtk_widget_show (GTK_WIDGET(priv->header_view));
541 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
544 /* status bar / progress */
545 status_hbox = gtk_hbox_new (FALSE, 0);
546 gtk_box_pack_start (GTK_BOX(status_hbox),
547 modest_widget_factory_get_folder_info_label (widget_factory),
549 gtk_box_pack_start (GTK_BOX(status_hbox),
550 modest_widget_factory_get_status_bar(widget_factory),
552 gtk_box_pack_start (GTK_BOX(status_hbox),
553 modest_widget_factory_get_progress_bar(widget_factory),
555 gtk_box_pack_start (GTK_BOX(status_hbox),
556 modest_widget_factory_get_online_toggle(widget_factory),
559 /* putting it all together... */
560 main_vbox = gtk_vbox_new (FALSE, 6);
561 gtk_box_pack_start (GTK_BOX(main_vbox), priv->menubar, FALSE, FALSE, 0);
562 gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, FALSE, 0);
563 gtk_box_pack_start (GTK_BOX(main_vbox), priv->main_paned, TRUE, TRUE,0);
564 gtk_box_pack_start (GTK_BOX(main_vbox), status_hbox, FALSE, FALSE, 0);
566 gtk_container_add (GTK_CONTAINER(obj), main_vbox);
567 restore_sizes (MODEST_MAIN_WINDOW(obj));
569 gtk_window_set_title (GTK_WINDOW(obj), "Modest");
570 gtk_window_set_icon (GTK_WINDOW(obj),
571 modest_icon_factory_get_icon (MODEST_APP_ICON));
573 gtk_widget_show_all (main_vbox);
575 g_signal_connect (G_OBJECT(obj), "delete-event",
576 G_CALLBACK(on_delete_event), obj);
578 return GTK_WIDGET(obj);