evolution-3.6.4/mail/e-mail-browser.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found e-mail-browser.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
clang-analyzer no-output-found e-mail-browser.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
   1 /*
   2  * e-mail-browser.c
   3  *
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU Lesser General Public
   6  * License as published by the Free Software Foundation; either
   7  * version 2 of the License, or (at your option) version 3.
   8  *
   9  * This program is distributed in the hope that it will be useful,
  10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12  * Lesser General Public License for more details.
  13  *
  14  * You should have received a copy of the GNU Lesser General Public
  15  * License along with the program; if not, see <http://www.gnu.org/licenses/>
  16  *
  17  *
  18  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  19  *
  20  */
  21 
  22 #ifdef HAVE_CONFIG_H
  23 #include <config.h>
  24 #endif
  25 
  26 #include "e-mail-browser.h"
  27 
  28 #include <string.h>
  29 #include <glib/gi18n.h>
  30 
  31 #include "e-util/e-util.h"
  32 #include "e-util/e-plugin-ui.h"
  33 #include "shell/e-shell.h"
  34 #include "shell/e-shell-utils.h"
  35 #include "shell/e-shell-settings.h"
  36 #include "widgets/misc/e-popup-action.h"
  37 #include "widgets/misc/e-preview-pane.h"
  38 
  39 #include "mail/e-mail-reader.h"
  40 #include "mail/e-mail-reader-utils.h"
  41 #include "mail/em-folder-tree-model.h"
  42 #include "mail/message-list.h"
  43 
  44 #define E_MAIL_BROWSER_GET_PRIVATE(obj) \
  45 	(G_TYPE_INSTANCE_GET_PRIVATE \
  46 	((obj), E_TYPE_MAIL_BROWSER, EMailBrowserPrivate))
  47 
  48 #define ACTION_GROUP_STANDARD		"action-group-standard"
  49 #define ACTION_GROUP_SEARCH_FOLDERS	"action-group-search-folders"
  50 
  51 struct _EMailBrowserPrivate {
  52 	EMailBackend *backend;
  53 	GtkUIManager *ui_manager;
  54 	EFocusTracker *focus_tracker;
  55 
  56 	EMailFormatterMode mode;
  57 
  58 	GtkWidget *main_menu;
  59 	GtkWidget *main_toolbar;
  60 	GtkWidget *message_list;
  61 	GtkWidget *preview_pane;
  62 	GtkWidget *statusbar;
  63 
  64 	guint show_deleted : 1;
  65 };
  66 
  67 enum {
  68 	PROP_0,
  69 	PROP_BACKEND,
  70 	PROP_FOCUS_TRACKER,
  71 	PROP_FORWARD_STYLE,
  72 	PROP_GROUP_BY_THREADS,
  73 	PROP_SHOW_DELETED,
  74 	PROP_REPLY_STYLE,
  75 	PROP_UI_MANAGER,
  76 	PROP_DISPLAY_MODE,
  77 };
  78 
  79 /* This is too trivial to put in a file.
  80  * It gets merged with the EMailReader UI. */
  81 static const gchar *ui =
  82 "<ui>"
  83 "  <menubar name='main-menu'>"
  84 "    <menu action='file-menu'>"
  85 "      <placeholder name='file-actions'/>"
  86 "      <placeholder name='print-actions'/>"
  87 "      <separator/>"
  88 "      <menuitem action='close'/>"
  89 "    </menu>"
  90 "    <menu action='edit-menu'>"
  91 "      <placeholder name='selection-actions'>"
  92 "        <menuitem action='cut-clipboard'/>"
  93 "        <menuitem action='copy-clipboard'/>"
  94 "        <menuitem action='paste-clipboard'/>"
  95 "        <separator/>"
  96 "        <menuitem action='select-all'/>"
  97 "      </placeholder>"
  98 "    </menu>"
  99 "  </menubar>"
 100 "</ui>";
 101 
 102 static void	e_mail_browser_reader_init
 103 					(EMailReaderInterface *interface);
 104 
 105 G_DEFINE_TYPE_WITH_CODE (
 106 	EMailBrowser,
 107 	e_mail_browser,
 108 	GTK_TYPE_WINDOW,
 109 	G_IMPLEMENT_INTERFACE (
 110 		E_TYPE_MAIL_READER, e_mail_browser_reader_init)
 111 	G_IMPLEMENT_INTERFACE (
 112 		E_TYPE_EXTENSIBLE, NULL))
 113 
 114 static void
 115 action_close_cb (GtkAction *action,
 116                  EMailBrowser *browser)
 117 {
 118 	e_mail_browser_close (browser);
 119 }
 120 
 121 static GtkActionEntry mail_browser_entries[] = {
 122 
 123 	{ "close",
 124 	  GTK_STOCK_CLOSE,
 125 	  NULL,
 126 	  NULL,
 127 	  N_("Close this window"),
 128 	  G_CALLBACK (action_close_cb) },
 129 
 130 	{ "copy-clipboard",
 131 	  GTK_STOCK_COPY,
 132 	  NULL,
 133 	  NULL,
 134 	  N_("Copy the selection"),
 135 	  NULL },  /* Handled by EFocusTracker */
 136 
 137 	{ "cut-clipboard",
 138 	  GTK_STOCK_CUT,
 139 	  NULL,
 140 	  NULL,
 141 	  N_("Cut the selection"),
 142 	  NULL },  /* Handled by EFocusTracker */
 143 
 144 	{ "paste-clipboard",
 145 	  GTK_STOCK_PASTE,
 146 	  NULL,
 147 	  NULL,
 148 	  N_("Paste the clipboard"),
 149 	  NULL },  /* Handled by EFocusTracker */
 150 
 151 	{ "select-all",
 152 	  GTK_STOCK_SELECT_ALL,
 153 	  NULL,
 154 	  NULL,
 155 	  N_("Select all text"),
 156 	  NULL },  /* Handled by EFocusTracker */
 157 
 158 	/*** Menus ***/
 159 
 160 	{ "file-menu",
 161 	  NULL,
 162 	  N_("_File"),
 163 	  NULL,
 164 	  NULL,
 165 	  NULL },
 166 
 167 	{ "edit-menu",
 168 	  NULL,
 169 	  N_("_Edit"),
 170 	  NULL,
 171 	  NULL,
 172 	  NULL },
 173 
 174 	{ "view-menu",
 175 	  NULL,
 176 	  N_("_View"),
 177 	  NULL,
 178 	  NULL,
 179 	  NULL }
 180 };
 181 
 182 static EPopupActionEntry mail_browser_popup_entries[] = {
 183 
 184 	{ "popup-copy-clipboard",
 185 	  NULL,
 186 	  "copy-clipboard" }
 187 };
 188 
 189 static void
 190 mail_browser_menu_item_select_cb (EMailBrowser *browser,
 191                                   GtkWidget *widget)
 192 {
 193 	GtkAction *action;
 194 	GtkActivatable *activatable;
 195 	GtkStatusbar *statusbar;
 196 	const gchar *tooltip;
 197 	guint context_id;
 198 	gpointer data;
 199 
 200 	activatable = GTK_ACTIVATABLE (widget);
 201 	action = gtk_activatable_get_related_action (activatable);
 202 	tooltip = gtk_action_get_tooltip (action);
 203 
 204 	data = g_object_get_data (G_OBJECT (widget), "context-id");
 205 	context_id = GPOINTER_TO_UINT (data);
 206 
 207 	if (tooltip == NULL)
 208 		return;
 209 
 210 	statusbar = GTK_STATUSBAR (browser->priv->statusbar);
 211 	gtk_statusbar_push (statusbar, context_id, tooltip);
 212 }
 213 
 214 static void
 215 mail_browser_menu_item_deselect_cb (EMailBrowser *browser,
 216                                     GtkWidget *menu_item)
 217 {
 218 	GtkStatusbar *statusbar;
 219 	guint context_id;
 220 	gpointer data;
 221 
 222 	data = g_object_get_data (G_OBJECT (menu_item), "context-id");
 223 	context_id = GPOINTER_TO_UINT (data);
 224 
 225 	statusbar = GTK_STATUSBAR (browser->priv->statusbar);
 226 	gtk_statusbar_pop (statusbar, context_id);
 227 }
 228 
 229 static void
 230 mail_browser_connect_proxy_cb (EMailBrowser *browser,
 231                                GtkAction *action,
 232                                GtkWidget *proxy)
 233 {
 234 	GtkStatusbar *statusbar;
 235 	guint context_id;
 236 
 237 	if (!GTK_IS_MENU_ITEM (proxy))
 238 		return;
 239 
 240 	statusbar = GTK_STATUSBAR (browser->priv->statusbar);
 241 	context_id = gtk_statusbar_get_context_id (statusbar, G_STRFUNC);
 242 
 243 	g_object_set_data (
 244 		G_OBJECT (proxy), "context-id",
 245 		GUINT_TO_POINTER (context_id));
 246 
 247 	g_signal_connect_swapped (
 248 		proxy, "select",
 249 		G_CALLBACK (mail_browser_menu_item_select_cb), browser);
 250 
 251 	g_signal_connect_swapped (
 252 		proxy, "deselect",
 253 		G_CALLBACK (mail_browser_menu_item_deselect_cb), browser);
 254 }
 255 
 256 static void
 257 mail_browser_message_selected_cb (EMailBrowser *browser,
 258                                   const gchar *uid)
 259 {
 260 	CamelMessageInfo *info;
 261 	CamelFolder *folder;
 262 	EMailReader *reader;
 263 	EMailDisplay *display;
 264 	const gchar *title;
 265 	guint32 state;
 266 
 267 	reader = E_MAIL_READER (browser);
 268 	state = e_mail_reader_check_state (reader);
 269 	e_mail_reader_update_actions (reader, state);
 270 
 271 	if (uid == NULL)
 272 		return;
 273 
 274 	folder = e_mail_reader_get_folder (reader);
 275 	display = e_mail_reader_get_mail_display (reader);
 276 
 277 	info = camel_folder_get_message_info (folder, uid);
 278 
 279 	if (info == NULL)
 280 		return;
 281 
 282 	title = camel_message_info_subject (info);
 283 	if (title == NULL || *title == '\0')
 284 		title = _("(No Subject)");
 285 
 286 	gtk_window_set_title (GTK_WINDOW (browser), title);
 287 	gtk_widget_grab_focus (GTK_WIDGET (display));
 288 
 289 	camel_message_info_set_flags (
 290 		info, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
 291 	camel_folder_free_message_info (folder, info);
 292 }
 293 
 294 static gboolean
 295 close_on_idle_cb (gpointer browser)
 296 {
 297 	e_mail_browser_close (browser);
 298 	return FALSE;
 299 }
 300 
 301 static void
 302 mail_browser_message_list_built_cb (EMailBrowser *browser,
 303                                     MessageList *message_list)
 304 {
 305 	g_return_if_fail (E_IS_MAIL_BROWSER (browser));
 306 	g_return_if_fail (IS_MESSAGE_LIST (message_list));
 307 
 308 	if (!message_list_count (message_list))
 309 		/* Prioritize ahead of GTK+ redraws. */
 310 		g_idle_add_full (
 311 			G_PRIORITY_HIGH_IDLE,
 312 			close_on_idle_cb, browser, NULL);
 313 }
 314 
 315 static gboolean
 316 mail_browser_popup_event_cb (EMailBrowser *browser,
 317                              GdkEventButton *event,
 318                              const gchar *uri)
 319 {
 320 	EMailReader *reader;
 321 	EWebView *web_view;
 322 	GtkMenu *menu;
 323 	guint32 state;
 324 
 325 	if (uri != NULL)
 326 		return FALSE;
 327 
 328 	reader = E_MAIL_READER (browser);
 329 	web_view = E_WEB_VIEW (e_mail_reader_get_mail_display (reader));
 330 
 331 	if (e_web_view_get_cursor_image (web_view) != NULL)
 332 		return FALSE;
 333 
 334 	menu = e_mail_reader_get_popup_menu (reader);
 335 
 336 	state = e_mail_reader_check_state (reader);
 337 	e_mail_reader_update_actions (reader, state);
 338 
 339 	if (event == NULL)
 340 		gtk_menu_popup (
 341 			menu, NULL, NULL, NULL, NULL,
 342 			0, gtk_get_current_event_time ());
 343 	else
 344 		gtk_menu_popup (
 345 			menu, NULL, NULL, NULL, NULL,
 346 			event->button, event->time);
 347 
 348 	return TRUE;
 349 }
 350 
 351 static void
 352 mail_browser_status_message_cb (EMailBrowser *browser,
 353                                 const gchar *status_message)
 354 {
 355 	GtkStatusbar *statusbar;
 356 	guint context_id;
 357 
 358 	statusbar = GTK_STATUSBAR (browser->priv->statusbar);
 359 	context_id = gtk_statusbar_get_context_id (statusbar, G_STRFUNC);
 360 
 361 	/* Always pop first.  This prevents messages from piling up. */
 362 	gtk_statusbar_pop (statusbar, context_id);
 363 
 364 	if (status_message != NULL && *status_message != '\0')
 365 		gtk_statusbar_push (statusbar, context_id, status_message);
 366 }
 367 
 368 static void
 369 mail_browser_set_backend (EMailBrowser *browser,
 370                           EMailBackend *backend)
 371 {
 372 	g_return_if_fail (E_IS_MAIL_BACKEND (backend));
 373 	g_return_if_fail (browser->priv->backend == NULL);
 374 
 375 	browser->priv->backend = g_object_ref (backend);
 376 }
 377 
 378 static void
 379 mail_browser_set_property (GObject *object,
 380                            guint property_id,
 381                            const GValue *value,
 382                            GParamSpec *pspec)
 383 {
 384 	switch (property_id) {
 385 		case PROP_BACKEND:
 386 			mail_browser_set_backend (
 387 				E_MAIL_BROWSER (object),
 388 				g_value_get_object (value));
 389 			return;
 390 
 391 		case PROP_FORWARD_STYLE:
 392 			e_mail_reader_set_forward_style (
 393 				E_MAIL_READER (object),
 394 				g_value_get_enum (value));
 395 			return;
 396 
 397 		case PROP_GROUP_BY_THREADS:
 398 			e_mail_reader_set_group_by_threads (
 399 				E_MAIL_READER (object),
 400 				g_value_get_boolean (value));
 401 			return;
 402 
 403 		case PROP_REPLY_STYLE:
 404 			e_mail_reader_set_reply_style (
 405 				E_MAIL_READER (object),
 406 				g_value_get_enum (value));
 407 			return;
 408 
 409 		case PROP_SHOW_DELETED:
 410 			e_mail_browser_set_show_deleted (
 411 				E_MAIL_BROWSER (object),
 412 				g_value_get_boolean (value));
 413 			return;
 414 
 415 		case PROP_DISPLAY_MODE:
 416 			E_MAIL_BROWSER (object)->priv->mode =
 417 				g_value_get_int (value);
 418 			return;
 419 	}
 420 
 421 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 422 }
 423 
 424 static void
 425 mail_browser_get_property (GObject *object,
 426                            guint property_id,
 427                            GValue *value,
 428                            GParamSpec *pspec)
 429 {
 430 	switch (property_id) {
 431 		case PROP_BACKEND:
 432 			g_value_set_object (
 433 				value, e_mail_reader_get_backend (
 434 				E_MAIL_READER (object)));
 435 			return;
 436 
 437 		case PROP_FOCUS_TRACKER:
 438 			g_value_set_object (
 439 				value, e_mail_browser_get_focus_tracker (
 440 				E_MAIL_BROWSER (object)));
 441 			return;
 442 
 443 		case PROP_FORWARD_STYLE:
 444 			g_value_set_enum (
 445 				value, e_mail_reader_get_forward_style (
 446 				E_MAIL_READER (object)));
 447 			return;
 448 
 449 		case PROP_GROUP_BY_THREADS:
 450 			g_value_set_boolean (
 451 				value, e_mail_reader_get_group_by_threads (
 452 				E_MAIL_READER (object)));
 453 			return;
 454 
 455 		case PROP_REPLY_STYLE:
 456 			g_value_set_enum (
 457 				value, e_mail_reader_get_reply_style (
 458 				E_MAIL_READER (object)));
 459 			return;
 460 
 461 		case PROP_SHOW_DELETED:
 462 			g_value_set_boolean (
 463 				value, e_mail_browser_get_show_deleted (
 464 				E_MAIL_BROWSER (object)));
 465 			return;
 466 
 467 		case PROP_UI_MANAGER:
 468 			g_value_set_object (
 469 				value, e_mail_browser_get_ui_manager (
 470 				E_MAIL_BROWSER (object)));
 471 			return;
 472 
 473 		case PROP_DISPLAY_MODE:
 474 			g_value_set_int (
 475 				value, E_MAIL_BROWSER (object)->priv->mode);
 476 			return;
 477 	}
 478 
 479 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 480 }
 481 
 482 static void
 483 mail_browser_dispose (GObject *object)
 484 {
 485 	EMailBrowserPrivate *priv;
 486 
 487 	priv = E_MAIL_BROWSER_GET_PRIVATE (object);
 488 
 489 	if (priv->backend != NULL) {
 490 		g_object_unref (priv->backend);
 491 		priv->backend = NULL;
 492 	}
 493 
 494 	if (priv->ui_manager != NULL) {
 495 		g_object_unref (priv->ui_manager);
 496 		priv->ui_manager = NULL;
 497 	}
 498 
 499 	if (priv->focus_tracker != NULL) {
 500 		g_object_unref (priv->focus_tracker);
 501 		priv->focus_tracker = NULL;
 502 	}
 503 
 504 	if (priv->main_menu != NULL) {
 505 		g_object_unref (priv->main_menu);
 506 		priv->main_menu = NULL;
 507 	}
 508 
 509 	if (priv->main_toolbar != NULL) {
 510 		g_object_unref (priv->main_toolbar);
 511 		priv->main_toolbar = NULL;
 512 	}
 513 
 514 	if (priv->message_list != NULL) {
 515 		/* This will cancel a regen operation. */
 516 		gtk_widget_destroy (priv->message_list);
 517 		priv->message_list = NULL;
 518 	}
 519 
 520 	if (priv->preview_pane != NULL) {
 521 		g_object_unref (priv->preview_pane);
 522 		priv->preview_pane = NULL;
 523 	}
 524 
 525 	if (priv->statusbar != NULL) {
 526 		g_object_unref (priv->statusbar);
 527 		priv->statusbar = NULL;
 528 	}
 529 
 530 	/* Chain up to parent's dispose() method. */
 531 	G_OBJECT_CLASS (e_mail_browser_parent_class)->dispose (object);
 532 }
 533 
 534 static void
 535 mail_browser_constructed (GObject *object)
 536 {
 537 	EMailBrowser *browser;
 538 	EMailReader *reader;
 539 	EMailBackend *backend;
 540 	EMailSession *session;
 541 	EMailDisplay *display;
 542 	EShellBackend *shell_backend;
 543 	EShell *shell;
 544 	EFocusTracker *focus_tracker;
 545 	GSettings *settings;
 546 	GtkAccelGroup *accel_group;
 547 	GtkActionGroup *action_group;
 548 	GtkAction *action;
 549 	GtkUIManager *ui_manager;
 550 	GtkWidget *container;
 551 	GtkWidget *widget;
 552 	const gchar *domain;
 553 	const gchar *id;
 554 	guint merge_id;
 555 
 556 	/* Chain up to parent's constructed() method. */
 557 	G_OBJECT_CLASS (e_mail_browser_parent_class)->constructed (object);
 558 
 559 	browser = E_MAIL_BROWSER (object);
 560 	reader = E_MAIL_READER (object);
 561 	backend = e_mail_reader_get_backend (reader);
 562 	session = e_mail_backend_get_session (backend);
 563 
 564 	shell_backend = E_SHELL_BACKEND (backend);
 565 	shell = e_shell_backend_get_shell (shell_backend);
 566 
 567 	ui_manager = e_ui_manager_new ();
 568 	e_shell_configure_ui_manager (shell, E_UI_MANAGER (ui_manager));
 569 
 570 	browser->priv->ui_manager = ui_manager;
 571 	domain = GETTEXT_PACKAGE;
 572 
 573 	gtk_application_add_window (
 574 		GTK_APPLICATION (shell), GTK_WINDOW (object));
 575 
 576 	/* The message list is a widget, but it is not shown in the browser.
 577 	 * Unfortunately, the widget is inseparable from its model, and the
 578 	 * model is all we need. */
 579 	browser->priv->message_list = message_list_new (session);
 580 	g_object_ref_sink (browser->priv->message_list);
 581 
 582 	g_signal_connect_swapped (
 583 		browser->priv->message_list, "message-selected",
 584 		G_CALLBACK (mail_browser_message_selected_cb), object);
 585 
 586 	g_signal_connect_swapped (
 587 		browser->priv->message_list, "message-list-built",
 588 		G_CALLBACK (mail_browser_message_list_built_cb), object);
 589 
 590 	display = g_object_new (
 591 		E_TYPE_MAIL_DISPLAY,
 592 		"mode", E_MAIL_BROWSER (object)->priv->mode, NULL);
 593 
 594 	g_signal_connect_swapped (
 595 		display, "popup-event",
 596 		G_CALLBACK (mail_browser_popup_event_cb), object);
 597 
 598 	g_signal_connect_swapped (
 599 		display, "status-message",
 600 		G_CALLBACK (mail_browser_status_message_cb), object);
 601 
 602 	widget = e_preview_pane_new (E_WEB_VIEW (display));
 603 	browser->priv->preview_pane = g_object_ref (widget);
 604 	gtk_widget_show (widget);
 605 
 606 	action_group = gtk_action_group_new (ACTION_GROUP_STANDARD);
 607 	gtk_action_group_set_translation_domain (action_group, domain);
 608 	gtk_action_group_add_actions (
 609 		action_group, mail_browser_entries,
 610 		G_N_ELEMENTS (mail_browser_entries), object);
 611 	e_action_group_add_popup_actions (
 612 		action_group, mail_browser_popup_entries,
 613 		G_N_ELEMENTS (mail_browser_popup_entries));
 614 	gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
 615 
 616 	/* For easy access.  Takes ownership of the reference. */
 617 
 618 	g_object_set_data_full (
 619 		object, ACTION_GROUP_STANDARD,
 620 		action_group, (GDestroyNotify) g_object_unref);
 621 
 622 	action_group = gtk_action_group_new (ACTION_GROUP_SEARCH_FOLDERS);
 623 	gtk_action_group_set_translation_domain (action_group, domain);
 624 	gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
 625 
 626 	/* For easy access.  Takes ownership of the reference. */
 627 	g_object_set_data_full (
 628 		object, ACTION_GROUP_SEARCH_FOLDERS,
 629 		action_group, (GDestroyNotify) g_object_unref);
 630 
 631 	e_mail_reader_init (reader, TRUE, TRUE);
 632 
 633 	e_ui_manager_add_ui_from_file (
 634 		E_UI_MANAGER (ui_manager), E_MAIL_READER_UI_DEFINITION);
 635 	e_ui_manager_add_ui_from_string (
 636 		E_UI_MANAGER (ui_manager), ui, NULL);
 637 
 638 	merge_id = gtk_ui_manager_new_merge_id (GTK_UI_MANAGER (ui_manager));
 639 	e_mail_reader_create_charset_menu (reader, ui_manager, merge_id);
 640 
 641 	accel_group = gtk_ui_manager_get_accel_group (ui_manager);
 642 	gtk_window_add_accel_group (GTK_WINDOW (object), accel_group);
 643 
 644 	g_signal_connect_swapped (
 645 		ui_manager, "connect-proxy",
 646 		G_CALLBACK (mail_browser_connect_proxy_cb), object);
 647 
 648 	/* Configure an EFocusTracker to manage selection actions. */
 649 
 650 	focus_tracker = e_focus_tracker_new (GTK_WINDOW (object));
 651 	action = e_mail_reader_get_action (reader, "cut-clipboard");
 652 	e_focus_tracker_set_cut_clipboard_action (focus_tracker, action);
 653 	action = e_mail_reader_get_action (reader, "copy-clipboard");
 654 	e_focus_tracker_set_copy_clipboard_action (focus_tracker, action);
 655 	action = e_mail_reader_get_action (reader, "paste-clipboard");
 656 	e_focus_tracker_set_paste_clipboard_action (focus_tracker, action);
 657 	action = e_mail_reader_get_action (reader, "select-all");
 658 	e_focus_tracker_set_select_all_action (focus_tracker, action);
 659 	browser->priv->focus_tracker = focus_tracker;
 660 
 661 	/* Construct window widgets. */
 662 
 663 	widget = gtk_vbox_new (FALSE, 0);
 664 	gtk_container_add (GTK_CONTAINER (object), widget);
 665 	gtk_widget_show (widget);
 666 
 667 	container = widget;
 668 
 669 	widget = gtk_statusbar_new ();
 670 	gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0);
 671 	browser->priv->statusbar = g_object_ref (widget);
 672 	gtk_widget_show (widget);
 673 
 674 	widget = gtk_ui_manager_get_widget (ui_manager, "/main-menu");
 675 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
 676 	browser->priv->main_menu = g_object_ref (widget);
 677 	gtk_widget_show (widget);
 678 
 679 	widget = gtk_ui_manager_get_widget (ui_manager, "/main-toolbar");
 680 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
 681 	browser->priv->main_toolbar = g_object_ref (widget);
 682 	gtk_widget_show (widget);
 683 
 684 	gtk_style_context_add_class (
 685 		gtk_widget_get_style_context (widget),
 686 		GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
 687 
 688 	gtk_container_add (GTK_CONTAINER (container), browser->priv->preview_pane);
 689 
 690 	/* Bind GObject properties to GSettings keys. */
 691 
 692 	settings = g_settings_new ("org.gnome.evolution.mail");
 693 
 694 	g_settings_bind (
 695 		settings, "show-deleted",
 696 		reader, "show-deleted",
 697 		G_SETTINGS_BIND_DEFAULT);
 698 
 699 	g_object_unref (settings);
 700 
 701 	id = "org.gnome.evolution.mail.browser";
 702 	e_plugin_ui_register_manager (ui_manager, id, object);
 703 	e_plugin_ui_enable_manager (ui_manager, id);
 704 
 705 	e_extensible_load_extensions (E_EXTENSIBLE (object));
 706 }
 707 
 708 static gboolean
 709 mail_browser_key_press_event (GtkWidget *widget,
 710                               GdkEventKey *event)
 711 {
 712 	if (event->keyval == GDK_KEY_Escape) {
 713 		e_mail_browser_close (E_MAIL_BROWSER (widget));
 714 		return TRUE;
 715 	}
 716 
 717 	/* Chain up to parent's key_press_event() method. */
 718 	return GTK_WIDGET_CLASS (e_mail_browser_parent_class)->
 719 		key_press_event (widget, event);
 720 }
 721 
 722 static GtkActionGroup *
 723 mail_browser_get_action_group (EMailReader *reader,
 724                                EMailReaderActionGroup group)
 725 {
 726 	const gchar *group_name;
 727 
 728 	switch (group) {
 729 		case E_MAIL_READER_ACTION_GROUP_STANDARD:
 730 			group_name = ACTION_GROUP_STANDARD;
 731 			break;
 732 		case E_MAIL_READER_ACTION_GROUP_SEARCH_FOLDERS:
 733 			group_name = ACTION_GROUP_SEARCH_FOLDERS;
 734 			break;
 735 		default:
 736 			g_return_val_if_reached (NULL);
 737 	}
 738 
 739 	return g_object_get_data (G_OBJECT (reader), group_name);
 740 }
 741 
 742 static EMailBackend *
 743 mail_browser_get_backend (EMailReader *reader)
 744 {
 745 	EMailBrowser *browser;
 746 
 747 	browser = E_MAIL_BROWSER (reader);
 748 
 749 	return browser->priv->backend;
 750 }
 751 
 752 static gboolean
 753 mail_browser_get_hide_deleted (EMailReader *reader)
 754 {
 755 	EMailBrowser *browser;
 756 
 757 	browser = E_MAIL_BROWSER (reader);
 758 
 759 	return !e_mail_browser_get_show_deleted (browser);
 760 }
 761 
 762 static EMailDisplay *
 763 mail_browser_get_mail_display (EMailReader *reader)
 764 {
 765 	EMailBrowserPrivate *priv;
 766 
 767 	priv = E_MAIL_BROWSER_GET_PRIVATE (E_MAIL_BROWSER (reader));
 768 
 769 	return E_MAIL_DISPLAY (e_preview_pane_get_web_view (
 770 					E_PREVIEW_PANE (priv->preview_pane)));
 771 }
 772 
 773 static GtkWidget *
 774 mail_browser_get_message_list (EMailReader *reader)
 775 {
 776 	EMailBrowser *browser;
 777 
 778 	browser = E_MAIL_BROWSER (reader);
 779 
 780 	return browser->priv->message_list;
 781 }
 782 
 783 static GtkMenu *
 784 mail_browser_get_popup_menu (EMailReader *reader)
 785 {
 786 	EMailBrowser *browser;
 787 	GtkUIManager *ui_manager;
 788 	GtkWidget *widget;
 789 
 790 	browser = E_MAIL_BROWSER (reader);
 791 	ui_manager = e_mail_browser_get_ui_manager (browser);
 792 	widget = gtk_ui_manager_get_widget (ui_manager, "/mail-preview-popup");
 793 
 794 	return GTK_MENU (widget);
 795 }
 796 
 797 static EPreviewPane *
 798 mail_browser_get_preview_pane (EMailReader *reader)
 799 {
 800 	EMailBrowser *browser;
 801 
 802 	browser = E_MAIL_BROWSER (reader);
 803 
 804 	return E_PREVIEW_PANE (browser->priv->preview_pane);
 805 }
 806 
 807 static GtkWindow *
 808 mail_browser_get_window (EMailReader *reader)
 809 {
 810 	return GTK_WINDOW (reader);
 811 }
 812 
 813 static void
 814 mail_browser_set_message (EMailReader *reader,
 815                           const gchar *uid)
 816 {
 817 	EMailReaderInterface *interface;
 818 	CamelMessageInfo *info;
 819 	CamelFolder *folder;
 820 
 821 	/* Chain up to parent's set_message() method. */
 822 	interface = g_type_default_interface_peek (E_TYPE_MAIL_READER);
 823 	interface->set_message (reader, uid);
 824 
 825 	if (uid == NULL) {
 826 		e_mail_browser_close (E_MAIL_BROWSER (reader));
 827 		return;
 828 	}
 829 
 830 	folder = e_mail_reader_get_folder (reader);
 831 	info = camel_folder_get_message_info (folder, uid);
 832 
 833 	if (info != NULL) {
 834 		gtk_window_set_title (
 835 			GTK_WINDOW (reader),
 836 			camel_message_info_subject (info));
 837 		camel_folder_free_message_info (folder, info);
 838 	}
 839 }
 840 
 841 static void
 842 e_mail_browser_class_init (EMailBrowserClass *class)
 843 {
 844 	GObjectClass *object_class;
 845 	GtkWidgetClass *widget_class;
 846 
 847 	g_type_class_add_private (class, sizeof (EMailBrowserPrivate));
 848 
 849 	object_class = G_OBJECT_CLASS (class);
 850 	object_class->set_property = mail_browser_set_property;
 851 	object_class->get_property = mail_browser_get_property;
 852 	object_class->dispose = mail_browser_dispose;
 853 	object_class->constructed = mail_browser_constructed;
 854 
 855 	widget_class = GTK_WIDGET_CLASS (class);
 856 	widget_class->key_press_event = mail_browser_key_press_event;
 857 
 858 	g_object_class_install_property (
 859 		object_class,
 860 		PROP_BACKEND,
 861 		g_param_spec_object (
 862 			"backend",
 863 			"Mail Backend",
 864 			"The mail backend",
 865 			E_TYPE_MAIL_BACKEND,
 866 			G_PARAM_READWRITE |
 867 			G_PARAM_CONSTRUCT_ONLY));
 868 
 869 	g_object_class_install_property (
 870 		object_class,
 871 		PROP_FOCUS_TRACKER,
 872 		g_param_spec_object (
 873 			"focus-tracker",
 874 			"Focus Tracker",
 875 			NULL,
 876 			E_TYPE_FOCUS_TRACKER,
 877 			G_PARAM_READABLE));
 878 
 879 	/* Inherited from EMailReader */
 880 	g_object_class_override_property (
 881 		object_class,
 882 		PROP_FORWARD_STYLE,
 883 		"forward-style");
 884 
 885 	/* Inherited from EMailReader */
 886 	g_object_class_override_property (
 887 		object_class,
 888 		PROP_GROUP_BY_THREADS,
 889 		"group-by-threads");
 890 
 891 	/* Inherited from EMailReader */
 892 	g_object_class_override_property (
 893 		object_class,
 894 		PROP_REPLY_STYLE,
 895 		"reply-style");
 896 
 897 	g_object_class_install_property (
 898 		object_class,
 899 		PROP_SHOW_DELETED,
 900 		g_param_spec_boolean (
 901 			"show-deleted",
 902 			"Show Deleted",
 903 			"Show deleted messages",
 904 			FALSE,
 905 			G_PARAM_READWRITE));
 906 
 907 	g_object_class_install_property (
 908 		object_class,
 909 		PROP_DISPLAY_MODE,
 910 		g_param_spec_int (
 911 			"display-mode",
 912 			"Display Mode",
 913 			NULL,
 914 			0,
 915 			G_MAXINT,
 916 			E_MAIL_FORMATTER_MODE_NORMAL,
 917 			G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 918 }
 919 
 920 static void
 921 e_mail_browser_reader_init (EMailReaderInterface *interface)
 922 {
 923 	interface->get_action_group = mail_browser_get_action_group;
 924 	interface->get_backend = mail_browser_get_backend;
 925 	interface->get_mail_display = mail_browser_get_mail_display;
 926 	interface->get_hide_deleted = mail_browser_get_hide_deleted;
 927 	interface->get_message_list = mail_browser_get_message_list;
 928 	interface->get_popup_menu = mail_browser_get_popup_menu;
 929 	interface->get_preview_pane = mail_browser_get_preview_pane;
 930 	interface->get_window = mail_browser_get_window;
 931 	interface->set_message = mail_browser_set_message;
 932 }
 933 
 934 static void
 935 e_mail_browser_init (EMailBrowser *browser)
 936 {
 937 	browser->priv = E_MAIL_BROWSER_GET_PRIVATE (browser);
 938 
 939 	gtk_window_set_title (GTK_WINDOW (browser), _("Evolution"));
 940 	gtk_window_set_default_size (GTK_WINDOW (browser), 600, 400);
 941 
 942 	e_restore_window (
 943 		GTK_WINDOW (browser),
 944 		"/org/gnome/evolution/mail/browser-window/",
 945 		E_RESTORE_WINDOW_SIZE);
 946 }
 947 
 948 GtkWidget *
 949 e_mail_browser_new (EMailBackend *backend,
 950                     CamelFolder *folder,
 951                     const gchar *msg_uid,
 952                     EMailFormatterMode mode)
 953 {
 954 	GtkWidget *widget;
 955 
 956 	g_return_val_if_fail (E_IS_MAIL_BACKEND (backend), NULL);
 957 
 958 	widget= g_object_new (
 959 		E_TYPE_MAIL_BROWSER,
 960 		"backend", backend,
 961 		"display-mode", mode,
 962 		NULL);
 963 
 964 	return widget;
 965 }
 966 
 967 void
 968 e_mail_browser_close (EMailBrowser *browser)
 969 {
 970 	g_return_if_fail (E_IS_MAIL_BROWSER (browser));
 971 
 972 	gtk_widget_destroy (GTK_WIDGET (browser));
 973 }
 974 
 975 gboolean
 976 e_mail_browser_get_show_deleted (EMailBrowser *browser)
 977 {
 978 	g_return_val_if_fail (E_IS_MAIL_BROWSER (browser), FALSE);
 979 
 980 	return browser->priv->show_deleted;
 981 }
 982 
 983 void
 984 e_mail_browser_set_show_deleted (EMailBrowser *browser,
 985                                  gboolean show_deleted)
 986 {
 987 	g_return_if_fail (E_IS_MAIL_BROWSER (browser));
 988 
 989 	if (browser->priv->show_deleted == show_deleted)
 990 		return;
 991 
 992 	browser->priv->show_deleted = show_deleted;
 993 
 994 	g_object_notify (G_OBJECT (browser), "show-deleted");
 995 }
 996 
 997 EFocusTracker *
 998 e_mail_browser_get_focus_tracker (EMailBrowser *browser)
 999 {
1000 	g_return_val_if_fail (E_IS_MAIL_BROWSER (browser), NULL);
1001 
1002 	return browser->priv->focus_tracker;
1003 }
1004 
1005 GtkUIManager *
1006 e_mail_browser_get_ui_manager (EMailBrowser *browser)
1007 {
1008 	g_return_val_if_fail (E_IS_MAIL_BROWSER (browser), NULL);
1009 
1010 	return browser->priv->ui_manager;
1011 }