evolution-3.6.4/mail/e-mail-paned-view.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found e-mail-paned-view.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
clang-analyzer no-output-found e-mail-paned-view.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  * This program is free software; you can redistribute it and/or
   3  * modify it under the terms of the GNU Lesser General Public
   4  * License as published by the Free Software Foundation; either
   5  * version 2 of the License, or (at your option) version 3.
   6  *
   7  * This program is distributed in the hope that it will be useful,
   8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  10  * Lesser General Public License for more details.
  11  *
  12  * You should have received a copy of the GNU Lesser General Public
  13  * License along with the program; if not, see <http://www.gnu.org/licenses/>
  14  *
  15  *
  16  * Authors:
  17  *		Srinivasa Ragavan <sragavan@gnome.org>
  18  *
  19  * Copyright (C) 2010 Intel corporation. (www.intel.com)
  20  *
  21  */
  22 
  23 #ifdef HAVE_CONFIG_H
  24 #include <config.h>
  25 #endif
  26 
  27 #include <glib/gi18n.h>
  28 #include "e-mail-paned-view.h"
  29 
  30 #include "e-util/e-util-private.h"
  31 #include "widgets/menus/gal-view-etable.h"
  32 #include "widgets/menus/gal-view-instance.h"
  33 #include "widgets/misc/e-paned.h"
  34 #include "widgets/misc/e-preview-pane.h"
  35 #include "widgets/misc/e-search-bar.h"
  36 
  37 #include <shell/e-shell-window-actions.h>
  38 
  39 #include <libemail-engine/e-mail-folder-utils.h>
  40 #include <libemail-engine/e-mail-utils.h>
  41 #include <libemail-engine/mail-config.h>
  42 #include <libemail-engine/mail-ops.h>
  43 
  44 #include "em-utils.h"
  45 #include "message-list.h"
  46 #include "e-mail-reader-utils.h"
  47 
  48 #define E_MAIL_PANED_VIEW_GET_PRIVATE(obj) \
  49 	(G_TYPE_INSTANCE_GET_PRIVATE \
  50 	((obj), E_TYPE_MAIL_PANED_VIEW, EMailPanedViewPrivate))
  51 
  52 #define E_SHELL_WINDOW_ACTION_GROUP_MAIL(window) \
  53 	E_SHELL_WINDOW_ACTION_GROUP ((window), "mail")
  54 
  55 struct _EMailPanedViewPrivate {
  56 	GtkWidget *paned;
  57 	GtkWidget *scrolled_window;
  58 	GtkWidget *message_list;
  59 	GtkWidget *preview_pane;
  60 	GtkWidget *search_bar;
  61 
  62 	EMailDisplay *display;
  63 	GalViewInstance *view_instance;
  64 
  65 	/* ETable scrolling hack */
  66 	gdouble default_scrollbar_position;
  67 
  68 	guint paned_binding_id;
  69 
  70 	/* Signal handler IDs */
  71 	guint message_list_built_id;
  72 	guint enable_show_folder : 1;
  73 };
  74 
  75 enum {
  76 	PROP_0,
  77 	PROP_FORWARD_STYLE,
  78 	PROP_GROUP_BY_THREADS,
  79 	PROP_REPLY_STYLE
  80 };
  81 
  82 #define STATE_KEY_GROUP_BY_THREADS	"GroupByThreads"
  83 #define STATE_KEY_SELECTED_MESSAGE	"SelectedMessage"
  84 #define STATE_KEY_PREVIEW_VISIBLE	"PreviewVisible"
  85 #define STATE_GROUP_GLOBAL_FOLDER	"GlobalFolder"
  86 
  87 /* Forward Declarations */
  88 static void e_mail_paned_view_reader_init (EMailReaderInterface *interface);
  89 
  90 G_DEFINE_TYPE_WITH_CODE (
  91 	EMailPanedView, e_mail_paned_view, E_TYPE_MAIL_VIEW,
  92 	G_IMPLEMENT_INTERFACE (
  93 		E_TYPE_MAIL_READER, e_mail_paned_view_reader_init)
  94 	G_IMPLEMENT_INTERFACE (
  95 		E_TYPE_EXTENSIBLE, NULL))
  96 
  97 static void
  98 mail_paned_view_save_boolean (EMailView *view,
  99                               const gchar *key,
 100                               gboolean value)
 101 {
 102 	EShellView *shell_view;
 103 	EMailReader *reader;
 104 	CamelFolder *folder;
 105 	GKeyFile *key_file;
 106 	gchar *folder_uri;
 107 	gchar *group_name;
 108 
 109 	shell_view = e_mail_view_get_shell_view (view);
 110 	key_file = e_shell_view_get_state_key_file (shell_view);
 111 
 112 	reader = E_MAIL_READER (view);
 113 	folder = e_mail_reader_get_folder (reader);
 114 
 115 	if (folder == NULL)
 116 		return;
 117 
 118 	folder_uri = e_mail_folder_uri_from_folder (folder);
 119 	group_name = g_strdup_printf ("Folder %s", folder_uri);
 120 	g_key_file_set_boolean (key_file, group_name, key, value);
 121 	g_free (group_name);
 122 	g_free (folder_uri);
 123 
 124 	g_key_file_set_boolean (key_file, STATE_GROUP_GLOBAL_FOLDER, key, value);
 125 
 126 	e_shell_view_set_state_dirty (shell_view);
 127 }
 128 
 129 static void
 130 mail_paned_view_message_list_built_cb (EMailView *view,
 131                                        MessageList *message_list)
 132 {
 133 	EMailPanedViewPrivate *priv;
 134 	EShellView *shell_view;
 135 	EShellWindow *shell_window;
 136 	GKeyFile *key_file;
 137 
 138 	priv = E_MAIL_PANED_VIEW_GET_PRIVATE (view);
 139 
 140 	g_signal_handler_disconnect (
 141 		message_list, priv->message_list_built_id);
 142 	priv->message_list_built_id = 0;
 143 
 144 	shell_view = e_mail_view_get_shell_view (view);
 145 	shell_window = e_shell_view_get_shell_window (shell_view);
 146 
 147 	key_file = e_shell_view_get_state_key_file (shell_view);
 148 
 149 	if (message_list->cursor_uid != NULL)
 150 		;  /* do nothing */
 151 
 152 	else if (message_list->folder == NULL)
 153 		;  /* do nothing */
 154 
 155 	else if (e_shell_window_get_safe_mode (shell_window))
 156 		e_shell_window_set_safe_mode (shell_window, FALSE);
 157 
 158 	else {
 159 		CamelFolder *folder;
 160 		const gchar *key;
 161 		gchar *folder_uri;
 162 		gchar *group_name;
 163 		gchar *uid;
 164 
 165 		folder = message_list->folder;
 166 		folder_uri = e_mail_folder_uri_from_folder (folder);
 167 
 168 		key = STATE_KEY_SELECTED_MESSAGE;
 169 		group_name = g_strdup_printf ("Folder %s", folder_uri);
 170 		uid = g_key_file_get_string (key_file, group_name, key, NULL);
 171 		g_free (group_name);
 172 
 173 		g_free (folder_uri);
 174 
 175 		/* Use selection fallbacks if UID is not found. */
 176 		message_list_select_uid (message_list, uid, TRUE);
 177 
 178 		g_free (uid);
 179 	}
 180 }
 181 
 182 static void
 183 mail_paned_view_message_selected_cb (EMailView *view,
 184                                      const gchar *message_uid,
 185                                      MessageList *message_list)
 186 {
 187 	EShellView *shell_view;
 188 	CamelFolder *folder;
 189 	GKeyFile *key_file;
 190 	const gchar *key;
 191 	gchar *folder_uri;
 192 	gchar *group_name;
 193 
 194 	folder = message_list->folder;
 195 
 196 	/* This also gets triggered when selecting a store name on
 197 	 * the sidebar such as "On This Computer", in which case
 198 	 * 'folder' will be NULL. */
 199 	if (folder == NULL)
 200 		return;
 201 
 202 	shell_view = e_mail_view_get_shell_view (view);
 203 	key_file = e_shell_view_get_state_key_file (shell_view);
 204 
 205 	folder_uri = e_mail_folder_uri_from_folder (folder);
 206 
 207 	key = STATE_KEY_SELECTED_MESSAGE;
 208 	group_name = g_strdup_printf ("Folder %s", folder_uri);
 209 
 210 	if (message_uid != NULL)
 211 		g_key_file_set_string (key_file, group_name, key, message_uid);
 212 	else
 213 		g_key_file_remove_key (key_file, group_name, key, NULL);
 214 	e_shell_view_set_state_dirty (shell_view);
 215 
 216 	g_free (group_name);
 217 	g_free (folder_uri);
 218 }
 219 
 220 static void
 221 mail_paned_view_restore_state_cb (EShellWindow *shell_window,
 222                                   EShellView *shell_view,
 223                                   EMailPanedView *view)
 224 {
 225 	EMailPanedViewPrivate *priv;
 226 	GSettings *settings;
 227 
 228 	priv = E_MAIL_PANED_VIEW (view)->priv;
 229 
 230 	/* Bind GObject properties to GSettings keys. */
 231 
 232 	settings = g_settings_new ("org.gnome.evolution.mail");
 233 
 234 	g_settings_bind (
 235 		settings, "hpaned-size",
 236 		priv->paned, "hposition",
 237 		G_SETTINGS_BIND_DEFAULT);
 238 
 239 	g_settings_bind (
 240 		settings, "paned-size",
 241 		priv->paned, "vposition",
 242 		G_SETTINGS_BIND_DEFAULT);
 243 
 244 	g_object_unref (settings);
 245 }
 246 
 247 static void
 248 mail_paned_display_view_cb (EMailView *view,
 249                             GalView *gal_view)
 250 {
 251 	EMailReader *reader;
 252 	GtkWidget *message_list;
 253 
 254 	reader = E_MAIL_READER (view);
 255 	message_list = e_mail_reader_get_message_list (reader);
 256 
 257 	if (GAL_IS_VIEW_ETABLE (gal_view))
 258 		gal_view_etable_attach_tree (
 259 			GAL_VIEW_ETABLE (gal_view),
 260 			E_TREE (message_list));
 261 }
 262 
 263 static void
 264 mail_paned_view_notify_group_by_threads_cb (EMailReader *reader)
 265 {
 266 	gboolean group_by_threads;
 267 
 268 	group_by_threads = e_mail_reader_get_group_by_threads (reader);
 269 
 270 	mail_paned_view_save_boolean (
 271 		E_MAIL_VIEW (reader),
 272 		STATE_KEY_GROUP_BY_THREADS, group_by_threads);
 273 }
 274 
 275 static void
 276 mail_paned_view_set_property (GObject *object,
 277                               guint property_id,
 278                               const GValue *value,
 279                               GParamSpec *pspec)
 280 {
 281 	switch (property_id) {
 282 		case PROP_FORWARD_STYLE:
 283 			e_mail_reader_set_forward_style (
 284 				E_MAIL_READER (object),
 285 				g_value_get_enum (value));
 286 			return;
 287 
 288 		case PROP_GROUP_BY_THREADS:
 289 			e_mail_reader_set_group_by_threads (
 290 				E_MAIL_READER (object),
 291 				g_value_get_boolean (value));
 292 			return;
 293 
 294 		case PROP_REPLY_STYLE:
 295 			e_mail_reader_set_reply_style (
 296 				E_MAIL_READER (object),
 297 				g_value_get_enum (value));
 298 			return;
 299 	}
 300 
 301 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 302 }
 303 
 304 static void
 305 mail_paned_view_get_property (GObject *object,
 306                               guint property_id,
 307                               GValue *value,
 308                               GParamSpec *pspec)
 309 {
 310 	switch (property_id) {
 311 		case PROP_FORWARD_STYLE:
 312 			g_value_set_enum (
 313 				value,
 314 				e_mail_reader_get_forward_style (
 315 				E_MAIL_READER (object)));
 316 			return;
 317 
 318 		case PROP_GROUP_BY_THREADS:
 319 			g_value_set_boolean (
 320 				value,
 321 				e_mail_reader_get_group_by_threads (
 322 				E_MAIL_READER (object)));
 323 			return;
 324 
 325 		case PROP_REPLY_STYLE:
 326 			g_value_set_enum (
 327 				value,
 328 				e_mail_reader_get_reply_style (
 329 				E_MAIL_READER (object)));
 330 			return;
 331 	}
 332 
 333 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 334 }
 335 
 336 static void
 337 mail_paned_view_dispose (GObject *object)
 338 {
 339 	EMailPanedViewPrivate *priv;
 340 
 341 	priv = E_MAIL_PANED_VIEW_GET_PRIVATE (object);
 342 
 343 	if (priv->paned != NULL) {
 344 		g_object_unref (priv->paned);
 345 		priv->paned = NULL;
 346 	}
 347 
 348 	if (priv->scrolled_window != NULL) {
 349 		g_object_unref (priv->scrolled_window);
 350 		priv->scrolled_window = NULL;
 351 	}
 352 
 353 	if (priv->message_list != NULL) {
 354 		g_object_unref (priv->message_list);
 355 		priv->message_list = NULL;
 356 	}
 357 
 358 	if (priv->preview_pane != NULL) {
 359 		g_object_unref (priv->preview_pane);
 360 		priv->preview_pane = NULL;
 361 	}
 362 
 363 	if (priv->view_instance != NULL) {
 364 		g_object_unref (priv->view_instance);
 365 		priv->view_instance = NULL;
 366 	}
 367 
 368 	/* Chain up to parent's dispose() method. */
 369 	G_OBJECT_CLASS (e_mail_paned_view_parent_class)->dispose (object);
 370 }
 371 
 372 static GtkActionGroup *
 373 mail_paned_view_get_action_group (EMailReader *reader,
 374                                   EMailReaderActionGroup group)
 375 {
 376 	EMailView *view;
 377 	EShellView *shell_view;
 378 	EShellWindow *shell_window;
 379 	const gchar *group_name;
 380 
 381 	view = E_MAIL_VIEW (reader);
 382 	shell_view = e_mail_view_get_shell_view (view);
 383 	shell_window = e_shell_view_get_shell_window (shell_view);
 384 
 385 	switch (group) {
 386 		case E_MAIL_READER_ACTION_GROUP_STANDARD:
 387 			group_name = "mail";
 388 			break;
 389 		case E_MAIL_READER_ACTION_GROUP_SEARCH_FOLDERS:
 390 			group_name = "search-folders";
 391 			break;
 392 		default:
 393 			g_return_val_if_reached (NULL);
 394 	}
 395 
 396 	return e_shell_window_get_action_group (shell_window, group_name);
 397 }
 398 
 399 static EAlertSink *
 400 mail_paned_view_get_alert_sink (EMailReader *reader)
 401 {
 402 	EMailView *view;
 403 	EShellView *shell_view;
 404 	EShellContent *shell_content;
 405 
 406 	view = E_MAIL_VIEW (reader);
 407 	shell_view = e_mail_view_get_shell_view (view);
 408 	shell_content = e_shell_view_get_shell_content (shell_view);
 409 
 410 	return E_ALERT_SINK (shell_content);
 411 }
 412 
 413 static EMailBackend *
 414 mail_paned_view_get_backend (EMailReader *reader)
 415 {
 416 	EMailView *view;
 417 	EShellView *shell_view;
 418 	EShellBackend *shell_backend;
 419 
 420 	view = E_MAIL_VIEW (reader);
 421 	shell_view = e_mail_view_get_shell_view (view);
 422 	shell_backend = e_shell_view_get_shell_backend (shell_view);
 423 
 424 	return E_MAIL_BACKEND (shell_backend);
 425 }
 426 
 427 static EMailDisplay *
 428 mail_paned_view_get_mail_display (EMailReader *reader)
 429 {
 430 	EMailPanedViewPrivate *priv;
 431 
 432 	priv = E_MAIL_PANED_VIEW (reader)->priv;
 433 
 434 	return priv->display;
 435 }
 436 
 437 static gboolean
 438 mail_paned_view_get_hide_deleted (EMailReader *reader)
 439 {
 440 	return !e_mail_view_get_show_deleted (E_MAIL_VIEW (reader));
 441 }
 442 
 443 static GtkWidget *
 444 mail_paned_view_get_message_list (EMailReader *reader)
 445 {
 446 	EMailPanedView *paned_view;
 447 
 448 	paned_view = E_MAIL_PANED_VIEW (reader);
 449 
 450 	return paned_view->priv->message_list;
 451 }
 452 
 453 static GtkMenu *
 454 mail_paned_view_get_popup_menu (EMailReader *reader)
 455 {
 456 	EMailView *view;
 457 	EShellView *shell_view;
 458 	EShellWindow *shell_window;
 459 	GtkUIManager *ui_manager;
 460 	GtkWidget *widget;
 461 
 462 	view = E_MAIL_VIEW (reader);
 463 	shell_view = e_mail_view_get_shell_view (view);
 464 	shell_window = e_shell_view_get_shell_window (shell_view);
 465 
 466 	ui_manager = e_shell_window_get_ui_manager (shell_window);
 467 	widget = gtk_ui_manager_get_widget (ui_manager, "/mail-preview-popup");
 468 
 469 	return GTK_MENU (widget);
 470 }
 471 
 472 static EPreviewPane *
 473 mail_paned_view_get_preview_pane (EMailReader *reader)
 474 {
 475 	EMailPanedView *paned_view;
 476 
 477 	paned_view = E_MAIL_PANED_VIEW (reader);
 478 
 479 	return E_PREVIEW_PANE (paned_view->priv->preview_pane);
 480 }
 481 
 482 static GtkWindow *
 483 mail_paned_view_get_window (EMailReader *reader)
 484 {
 485 	EMailView *view;
 486 	EShellView *shell_view;
 487 	EShellWindow *shell_window;
 488 
 489 	view = E_MAIL_VIEW (reader);
 490 	shell_view = e_mail_view_get_shell_view (view);
 491 	shell_window = e_shell_view_get_shell_window (shell_view);
 492 
 493 	return GTK_WINDOW (shell_window);
 494 }
 495 
 496 static void
 497 mail_paned_view_set_folder (EMailReader *reader,
 498                             CamelFolder *folder)
 499 {
 500 	EMailPanedViewPrivate *priv;
 501 	EMailView *view;
 502 	EShell *shell;
 503 	EShellView *shell_view;
 504 	EShellWindow *shell_window;
 505 	EShellSettings *shell_settings;
 506 	EMailReaderInterface *default_interface;
 507 	GtkWidget *message_list;
 508 	GKeyFile *key_file;
 509 	gchar *folder_uri;
 510 	gchar *group_name;
 511 	const gchar *key;
 512 	gboolean value, global_view_settings;
 513 	GError *error = NULL;
 514 
 515 	priv = E_MAIL_PANED_VIEW_GET_PRIVATE (reader);
 516 
 517 	view = E_MAIL_VIEW (reader);
 518 	shell_view = e_mail_view_get_shell_view (view);
 519 	shell_window = e_shell_view_get_shell_window (shell_view);
 520 
 521 	shell = e_shell_window_get_shell (shell_window);
 522 	shell_settings = e_shell_get_shell_settings (shell);
 523 	global_view_settings = e_shell_settings_get_boolean (shell_settings, "mail-global-view-setting");
 524 
 525 	message_list = e_mail_reader_get_message_list (reader);
 526 
 527 	message_list_freeze (MESSAGE_LIST (message_list));
 528 
 529 	/* Chain up to interface's default set_folder() method. */
 530 	default_interface = g_type_default_interface_peek (E_TYPE_MAIL_READER);
 531 	default_interface->set_folder (reader, folder);
 532 
 533 	if (folder == NULL)
 534 		goto exit;
 535 
 536 	/* Only refresh the folder if we're online. */
 537 	if (e_shell_get_online (shell))
 538 		e_mail_reader_refresh_folder (reader, folder);
 539 
 540 	/* This is a one-time-only callback. */
 541 	if (MESSAGE_LIST (message_list)->cursor_uid == NULL &&
 542 		priv->message_list_built_id == 0)
 543 		priv->message_list_built_id = g_signal_connect_swapped (
 544 			message_list, "message-list-built",
 545 			G_CALLBACK (mail_paned_view_message_list_built_cb),
 546 			reader);
 547 
 548 	/* Restore the folder's preview and threaded state. */
 549 
 550 	folder_uri = e_mail_folder_uri_from_folder (folder);
 551 	key_file = e_shell_view_get_state_key_file (shell_view);
 552 	group_name = g_strdup_printf ("Folder %s", folder_uri);
 553 	g_free (folder_uri);
 554 
 555 	key = STATE_KEY_GROUP_BY_THREADS;
 556 	value = g_key_file_get_boolean (key_file, global_view_settings ? STATE_GROUP_GLOBAL_FOLDER : group_name, key, &error);
 557 	if (error != NULL) {
 558 		g_clear_error (&error);
 559 
 560 		value = !global_view_settings ||
 561 			g_key_file_get_boolean (key_file, STATE_GROUP_GLOBAL_FOLDER, key, &error);
 562 		if (error != NULL) {
 563 			g_clear_error (&error);
 564 			value = TRUE;
 565 		}
 566 	}
 567 
 568 	e_mail_reader_set_group_by_threads (reader, value);
 569 
 570 	key = STATE_KEY_PREVIEW_VISIBLE;
 571 	value = g_key_file_get_boolean (key_file, global_view_settings ? STATE_GROUP_GLOBAL_FOLDER : group_name, key, &error);
 572 	if (error != NULL) {
 573 		g_clear_error (&error);
 574 
 575 		value = !global_view_settings ||
 576 			g_key_file_get_boolean (key_file, STATE_GROUP_GLOBAL_FOLDER, key, &error);
 577 		if (error != NULL) {
 578 			g_clear_error (&error);
 579 			value = TRUE;
 580 		}
 581 	}
 582 
 583 	/* XXX This is a little confusing and needs rethought.  The
 584 	 *     EShellWindow:safe-mode property blocks automatic message
 585 	 *     selection, but the "mail-safe-list" shell setting blocks
 586 	 *     both the preview pane and automatic message selection. */
 587 	if (e_shell_settings_get_boolean (shell_settings, "mail-safe-list")) {
 588 		e_shell_settings_set_boolean (
 589 			shell_settings, "mail-safe-list", FALSE);
 590 		e_shell_window_set_safe_mode (shell_window, TRUE);
 591 		value = FALSE;
 592 	}
 593 
 594 	e_mail_view_set_preview_visible (E_MAIL_VIEW (reader), value);
 595 
 596 	g_free (group_name);
 597 
 598 exit:
 599 	message_list_thaw (MESSAGE_LIST (message_list));
 600 }
 601 
 602 static guint
 603 mail_paned_view_reader_open_selected_mail (EMailReader *reader)
 604 {
 605 	EMailPanedView *paned_view;
 606 	EMailPanedViewClass *class;
 607 
 608 	paned_view = E_MAIL_PANED_VIEW (reader);
 609 
 610 	class = E_MAIL_PANED_VIEW_GET_CLASS (paned_view);
 611 	g_return_val_if_fail (class->open_selected_mail != NULL, 0);
 612 
 613 	return class->open_selected_mail (paned_view);
 614 }
 615 
 616 static gboolean
 617 mail_paned_view_enable_show_folder (EMailReader *reader)
 618 {
 619 	EMailPanedView *paned_view;
 620 
 621 	paned_view = E_MAIL_PANED_VIEW (reader);
 622 
 623 	return paned_view->priv->enable_show_folder;
 624 }
 625 
 626 static void
 627 mail_paned_view_constructed (GObject *object)
 628 {
 629 	EMailPanedViewPrivate *priv;
 630 	EShellBackend *shell_backend;
 631 	EShellWindow *shell_window;
 632 	EShellView *shell_view;
 633 	EShell *shell;
 634 	EShellSettings *shell_settings;
 635 	EMailReader *reader;
 636 	EMailBackend *backend;
 637 	EMailSession *session;
 638 	EMailView *view;
 639 	GtkWidget *message_list;
 640 	GtkWidget *container;
 641 	GtkWidget *widget;
 642 
 643 	priv = E_MAIL_PANED_VIEW_GET_PRIVATE (object);
 644 
 645 	priv->display = g_object_new (
 646 		E_TYPE_MAIL_DISPLAY,
 647 		"headers-collapsable", TRUE, NULL);
 648 
 649 	view = E_MAIL_VIEW (object);
 650 	shell_view = e_mail_view_get_shell_view (view);
 651 	shell_window = e_shell_view_get_shell_window (shell_view);
 652 	shell_backend = e_shell_view_get_shell_backend (shell_view);
 653 	shell = e_shell_window_get_shell (shell_window);
 654 	shell_settings = e_shell_get_shell_settings (shell);
 655 
 656 	backend = E_MAIL_BACKEND (shell_backend);
 657 	session = e_mail_backend_get_session (backend);
 658 
 659 	g_object_bind_property (
 660 		shell_settings, "paned-view-headers-state",
 661 		priv->display, "headers-collapsed",
 662 		G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
 663 
 664 	/* Build content widgets. */
 665 
 666 	container = GTK_WIDGET (object);
 667 
 668 	widget = e_paned_new (GTK_ORIENTATION_VERTICAL);
 669 	gtk_container_add (GTK_CONTAINER (container), widget);
 670 	priv->paned = g_object_ref (widget);
 671 	gtk_widget_show (widget);
 672 
 673 	g_object_bind_property (
 674 		object, "orientation",
 675 		widget, "orientation",
 676 		G_BINDING_SYNC_CREATE);
 677 
 678 	container = priv->paned;
 679 
 680 	widget = gtk_scrolled_window_new (NULL, NULL);
 681 	gtk_scrolled_window_set_policy (
 682 		GTK_SCROLLED_WINDOW (widget),
 683 		GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
 684 	gtk_scrolled_window_set_shadow_type (
 685 		GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
 686 	priv->scrolled_window = g_object_ref (widget);
 687 	gtk_paned_pack1 (GTK_PANED (container), widget, TRUE, FALSE);
 688 	gtk_widget_show (widget);
 689 
 690 	container = widget;
 691 
 692 	widget = message_list_new (session);
 693 	gtk_container_add (GTK_CONTAINER (container), widget);
 694 	priv->message_list = g_object_ref (widget);
 695 	gtk_widget_show (widget);
 696 
 697 	container = priv->paned;
 698 
 699 	widget = e_preview_pane_new (E_WEB_VIEW (priv->display));
 700 	gtk_paned_pack2 (GTK_PANED (container), widget, FALSE, FALSE);
 701 	priv->preview_pane = g_object_ref (widget);
 702 	gtk_widget_show (GTK_WIDGET (priv->display));
 703 	gtk_widget_show (widget);
 704 
 705 	g_object_bind_property (
 706 		object, "preview-visible",
 707 		widget, "visible",
 708 		G_BINDING_SYNC_CREATE);
 709 
 710 	/* Load the view instance. */
 711 
 712 	e_mail_view_update_view_instance (E_MAIL_VIEW (object));
 713 
 714 	/* Message list customizations. */
 715 
 716 	e_mail_reader_init (E_MAIL_READER (object), FALSE, TRUE);
 717 
 718 	reader = E_MAIL_READER (object);
 719 	message_list = e_mail_reader_get_message_list (reader);
 720 
 721 	g_signal_connect_swapped (
 722 		message_list, "message-selected",
 723 		G_CALLBACK (mail_paned_view_message_selected_cb),
 724 		object);
 725 
 726 	/* Restore pane positions from the last session once
 727 	 * the shell view is fully initialized and visible. */
 728 	g_signal_connect (
 729 		shell_window, "shell-view-created::mail",
 730 		G_CALLBACK (mail_paned_view_restore_state_cb),
 731 		object);
 732 
 733 	/* Do this after creating the message list.  Our
 734 	 * set_preview_visible() method relies on it. */
 735 	e_mail_view_set_preview_visible (view, TRUE);
 736 
 737 	e_extensible_load_extensions (E_EXTENSIBLE (object));
 738 
 739 	/* Chain up to parent's constructed() method. */
 740 	G_OBJECT_CLASS (e_mail_paned_view_parent_class)->constructed (object);
 741 }
 742 
 743 static void
 744 mail_paned_view_set_search_strings (EMailView *view,
 745                                     GSList *search_strings)
 746 {
 747 	EMailDisplay *display;
 748 	EWebView *web_view;
 749 	EMailReader *reader;
 750 
 751 	reader = E_MAIL_READER (view);
 752 	display = e_mail_reader_get_mail_display (reader);
 753 	if (!display)
 754 		return;
 755 
 756 	web_view = E_WEB_VIEW (display);
 757 
 758 	e_web_view_clear_highlights (web_view);
 759 
 760 	while (search_strings != NULL) {
 761 		e_web_view_add_highlight (web_view, search_strings->data);
 762 		search_strings = g_slist_next (search_strings);
 763 	}
 764 }
 765 
 766 static GalViewInstance *
 767 mail_paned_view_get_view_instance (EMailView *view)
 768 {
 769 	EMailPanedView *paned_view;
 770 
 771 	paned_view = E_MAIL_PANED_VIEW (view);
 772 
 773 	return paned_view->priv->view_instance;
 774 }
 775 
 776 static gchar *
 777 empv_create_view_id (CamelFolder *folder)
 778 {
 779 	GChecksum *checksum;
 780 	gchar *res, *folder_uri;
 781 
 782 	g_return_val_if_fail (folder != NULL, NULL);
 783 
 784 	folder_uri = e_mail_folder_uri_from_folder (folder);
 785 	g_return_val_if_fail (folder_uri != NULL, NULL);
 786 
 787 	/* to be able to migrate previously saved views */
 788 	e_filename_make_safe (folder_uri);
 789 
 790 	/* use MD5 checksum of the folder URI, to not depend on its length */
 791 	checksum = g_checksum_new (G_CHECKSUM_MD5);
 792 	g_checksum_update (checksum, (const guchar *) folder_uri, -1);
 793 
 794 	res = g_strdup (g_checksum_get_string (checksum));
 795 
 796 	g_checksum_free (checksum);
 797 	g_free (folder_uri);
 798 
 799 	return res;
 800 }
 801 
 802 static void
 803 mail_paned_view_update_view_instance (EMailView *view)
 804 {
 805 	EMailPanedViewPrivate *priv;
 806 	EMailReader *reader;
 807 	EShell *shell;
 808 	EShellView *shell_view;
 809 	EShellWindow *shell_window;
 810 	EShellViewClass *shell_view_class;
 811 	EShellSettings *shell_settings;
 812 	ESourceRegistry *registry;
 813 	GalViewCollection *view_collection;
 814 	GalViewInstance *view_instance;
 815 	CamelFolder *folder;
 816 	GtkOrientable *orientable;
 817 	GtkOrientation orientation;
 818 	gboolean outgoing_folder;
 819 	gboolean show_vertical_view;
 820 	gchar *view_id;
 821 
 822 	priv = E_MAIL_PANED_VIEW_GET_PRIVATE (view);
 823 
 824 	shell_view = e_mail_view_get_shell_view (view);
 825 	shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
 826 	view_collection = shell_view_class->view_collection;
 827 
 828 	shell_window = e_shell_view_get_shell_window (shell_view);
 829 	shell = e_shell_window_get_shell (shell_window);
 830 	registry = e_shell_get_registry (shell);
 831 	shell_settings = e_shell_get_shell_settings (shell);
 832 
 833 	reader = E_MAIL_READER (view);
 834 	folder = e_mail_reader_get_folder (reader);
 835 
 836 	/* If no folder is selected, return silently. */
 837 	if (folder == NULL)
 838 		return;
 839 
 840 	if (priv->view_instance != NULL) {
 841 		g_object_unref (priv->view_instance);
 842 		priv->view_instance = NULL;
 843 	}
 844 
 845 	view_id = empv_create_view_id (folder);
 846 	e_filename_make_safe (view_id);
 847 
 848 	outgoing_folder =
 849 		em_utils_folder_is_drafts (registry, folder) ||
 850 		em_utils_folder_is_outbox (registry, folder) ||
 851 		em_utils_folder_is_sent (registry, folder);
 852 
 853 	if (e_shell_settings_get_boolean (shell_settings, "mail-global-view-setting"))
 854 		view_instance = e_shell_view_new_view_instance (
 855 			shell_view, outgoing_folder ?
 856 			"global_view_sent_setting" : "global_view_setting");
 857 	else
 858 		view_instance = e_shell_view_new_view_instance (shell_view, view_id);
 859 
 860 	priv->view_instance = view_instance;
 861 
 862 	orientable = GTK_ORIENTABLE (view);
 863 	orientation = gtk_orientable_get_orientation (orientable);
 864 	show_vertical_view =
 865 		(orientation == GTK_ORIENTATION_HORIZONTAL) &&
 866 		!e_shell_settings_get_boolean (
 867 		shell_settings, "mail-global-view-setting");
 868 
 869 	if (show_vertical_view) {
 870 		gchar *filename;
 871 		gchar *safe_view_id;
 872 
 873 		/* Force the view instance into vertical view. */
 874 
 875 		g_free (view_instance->custom_filename);
 876 		g_free (view_instance->current_view_filename);
 877 
 878 		safe_view_id = g_strdup (view_id);
 879 		e_filename_make_safe (safe_view_id);
 880 
 881 		filename = g_strdup_printf (
 882 			"custom_wide_view-%s.xml", safe_view_id);
 883 		view_instance->custom_filename = g_build_filename (
 884 			view_collection->local_dir, filename, NULL);
 885 		g_free (filename);
 886 
 887 		filename = g_strdup_printf (
 888 			"current_wide_view-%s.xml", safe_view_id);
 889 		view_instance->current_view_filename = g_build_filename (
 890 			view_collection->local_dir, filename, NULL);
 891 		g_free (filename);
 892 
 893 		g_free (safe_view_id);
 894 	}
 895 
 896 	g_free (view_id);
 897 
 898 	if (outgoing_folder) {
 899 		if (show_vertical_view)
 900 			gal_view_instance_set_default_view (
 901 				view_instance, "Wide_View_Sent");
 902 		else
 903 			gal_view_instance_set_default_view (
 904 				view_instance, "As_Sent_Folder");
 905 	} else if (show_vertical_view) {
 906 		gal_view_instance_set_default_view (
 907 			view_instance, "Wide_View_Normal");
 908 	}
 909 
 910 	gal_view_instance_load (view_instance);
 911 
 912 	if (!gal_view_instance_exists (view_instance)) {
 913 		gchar *state_filename;
 914 
 915 		state_filename = mail_config_folder_to_cachename (
 916 			folder, "et-header-");
 917 
 918 		if (g_file_test (state_filename, G_FILE_TEST_IS_REGULAR)) {
 919 			ETableSpecification *spec;
 920 			ETableState *state;
 921 			GalView *view;
 922 			gchar *spec_filename;
 923 
 924 			spec = e_table_specification_new ();
 925 			spec_filename = g_build_filename (
 926 				EVOLUTION_ETSPECDIR,
 927 				"message-list.etspec",
 928 				NULL);
 929 			e_table_specification_load_from_file (
 930 				spec, spec_filename);
 931 			g_free (spec_filename);
 932 
 933 			state = e_table_state_new ();
 934 			view = gal_view_etable_new (spec, "");
 935 
 936 			e_table_state_load_from_file (
 937 				state, state_filename);
 938 			gal_view_etable_set_state (
 939 				GAL_VIEW_ETABLE (view), state);
 940 			gal_view_instance_set_custom_view (
 941 				view_instance, view);
 942 
 943 			g_object_unref (state);
 944 			g_object_unref (view);
 945 			g_object_unref (spec);
 946 		}
 947 
 948 		g_free (state_filename);
 949 	}
 950 
 951 	g_signal_connect_swapped (
 952 		view_instance, "display-view",
 953 		G_CALLBACK (mail_paned_display_view_cb), view);
 954 
 955 	mail_paned_display_view_cb (
 956 		view, gal_view_instance_get_current_view (view_instance));
 957 }
 958 
 959 static void
 960 mail_paned_view_set_preview_visible (EMailView *view,
 961                                      gboolean preview_visible)
 962 {
 963 	EMailViewClass *parent_class;
 964 
 965 	/* If we're showing the preview, tell EMailReader to reload the
 966 	 * selected message.  This should force it to download the full
 967 	 * message if necessary, so we don't get an empty preview. */
 968 	if (preview_visible) {
 969 		EMailReader *reader;
 970 		GtkWidget *message_list;
 971 		const gchar *cursor_uid;
 972 
 973 		reader = E_MAIL_READER (view);
 974 		message_list = e_mail_reader_get_message_list (reader);
 975 		cursor_uid = MESSAGE_LIST (message_list)->cursor_uid;
 976 
 977 		if (cursor_uid != NULL)
 978 			e_mail_reader_set_message (reader, cursor_uid);
 979 	}
 980 
 981 	mail_paned_view_save_boolean (
 982 		E_MAIL_VIEW (view),
 983 		STATE_KEY_PREVIEW_VISIBLE, preview_visible);
 984 
 985 	/* Chain up to parent's set_preview_visible() method. */
 986 	parent_class = E_MAIL_VIEW_CLASS (e_mail_paned_view_parent_class);
 987 	parent_class->set_preview_visible (view, preview_visible);
 988 }
 989 
 990 static guint
 991 mail_paned_view_open_selected_mail (EMailPanedView *view)
 992 {
 993 	return e_mail_reader_open_selected (E_MAIL_READER (view));
 994 }
 995 
 996 static void
 997 e_mail_paned_view_class_init (EMailPanedViewClass *class)
 998 {
 999 	GObjectClass *object_class;
1000 	EMailViewClass *mail_view_class;
1001 
1002 	g_type_class_add_private (class, sizeof (EMailPanedViewPrivate));
1003 
1004 	object_class = G_OBJECT_CLASS (class);
1005 	object_class->dispose = mail_paned_view_dispose;
1006 	object_class->constructed = mail_paned_view_constructed;
1007 	object_class->set_property = mail_paned_view_set_property;
1008 	object_class->get_property = mail_paned_view_get_property;
1009 
1010 	mail_view_class = E_MAIL_VIEW_CLASS (class);
1011 	mail_view_class->set_search_strings = mail_paned_view_set_search_strings;
1012 	mail_view_class->get_view_instance = mail_paned_view_get_view_instance;
1013 	mail_view_class->update_view_instance = mail_paned_view_update_view_instance;
1014 
1015 	mail_view_class->set_preview_visible = mail_paned_view_set_preview_visible;
1016 
1017 	class->open_selected_mail = mail_paned_view_open_selected_mail;
1018 
1019 	/* Inherited from EMailReader */
1020 	g_object_class_override_property (
1021 		object_class,
1022 		PROP_FORWARD_STYLE,
1023 		"forward-style");
1024 
1025 	/* Inherited from EMailReader */
1026 	g_object_class_override_property (
1027 		object_class,
1028 		PROP_GROUP_BY_THREADS,
1029 		"group-by-threads");
1030 
1031 	/* Inherited from EMailReader */
1032 	g_object_class_override_property (
1033 		object_class,
1034 		PROP_REPLY_STYLE,
1035 		"reply-style");
1036 }
1037 
1038 static void
1039 e_mail_paned_view_reader_init (EMailReaderInterface *interface)
1040 {
1041 	interface->get_action_group = mail_paned_view_get_action_group;
1042 	interface->get_alert_sink = mail_paned_view_get_alert_sink;
1043 	interface->get_backend = mail_paned_view_get_backend;
1044 	interface->get_mail_display = mail_paned_view_get_mail_display;
1045 	interface->get_hide_deleted = mail_paned_view_get_hide_deleted;
1046 	interface->get_message_list = mail_paned_view_get_message_list;
1047 	interface->get_popup_menu = mail_paned_view_get_popup_menu;
1048 	interface->get_preview_pane = mail_paned_view_get_preview_pane;
1049 	interface->get_window = mail_paned_view_get_window;
1050 	interface->set_folder = mail_paned_view_set_folder;
1051 	interface->open_selected_mail = mail_paned_view_reader_open_selected_mail;
1052 	interface->enable_show_folder = mail_paned_view_enable_show_folder;
1053 }
1054 
1055 static void
1056 e_mail_paned_view_init (EMailPanedView *view)
1057 {
1058 	view->priv = E_MAIL_PANED_VIEW_GET_PRIVATE (view);
1059 	view->priv->enable_show_folder = FALSE;
1060 
1061 	g_signal_connect (
1062 		view, "notify::group-by-threads",
1063 		G_CALLBACK (mail_paned_view_notify_group_by_threads_cb),
1064 		NULL);
1065 }
1066 
1067 GtkWidget *
1068 e_mail_paned_view_new (EShellView *shell_view)
1069 {
1070 	g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
1071 
1072 	return g_object_new (
1073 		E_TYPE_MAIL_PANED_VIEW,
1074 		"shell-view", shell_view, NULL);
1075 }
1076 
1077 void
1078 e_mail_paned_view_hide_message_list_pane (EMailPanedView *view,
1079                                           gboolean visible)
1080 {
1081 	g_return_if_fail (E_IS_MAIL_PANED_VIEW (view));
1082 
1083 	if (visible)
1084 		gtk_widget_show (view->priv->scrolled_window);
1085 	else
1086 		gtk_widget_hide (view->priv->scrolled_window);
1087 }
1088 
1089 GtkWidget *
1090 e_mail_paned_view_get_preview (EMailPanedView *view)
1091 {
1092 	g_return_val_if_fail (E_IS_MAIL_PANED_VIEW (view), NULL);
1093 
1094 	return GTK_WIDGET (mail_paned_view_get_mail_display (E_MAIL_READER (view)));
1095 }
1096 
1097 void
1098 e_mail_paned_view_set_enable_show_folder (EMailPanedView *view,
1099                                           gboolean set)
1100 {
1101 	view->priv->enable_show_folder = set;
1102 }