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

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found e-mail-reader.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
clang-analyzer no-output-found e-mail-reader.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-reader.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-reader.h"
  27 
  28 #include <glib/gi18n.h>
  29 #include <gdk/gdkkeysyms.h>
  30 
  31 #ifdef HAVE_XFREE
  32 #include <X11/XF86keysym.h>
  33 #endif
  34 
  35 #include "e-util/e-charset.h"
  36 #include "e-util/e-util.h"
  37 #include "libevolution-utils/e-alert-dialog.h"
  38 #include "shell/e-shell-utils.h"
  39 #include "widgets/misc/e-popup-action.h"
  40 #include "widgets/misc/e-menu-tool-action.h"
  41 
  42 #include "libemail-utils/mail-mt.h"
  43 
  44 #include "libemail-engine/mail-ops.h"
  45 #include "libemail-engine/e-mail-utils.h"
  46 #include "libemail-engine/e-mail-enumtypes.h"
  47 
  48 #include "mail/e-mail-backend.h"
  49 #include "mail/e-mail-browser.h"
  50 #include "mail/e-mail-reader-utils.h"
  51 #include "mail/e-mail-ui-session.h"
  52 #include "mail/e-mail-view.h"
  53 #include "mail/em-composer-utils.h"
  54 #include "mail/em-event.h"
  55 #include "mail/em-folder-selector.h"
  56 #include "mail/em-folder-tree.h"
  57 #include "mail/em-utils.h"
  58 #include "mail/mail-autofilter.h"
  59 #include "mail/mail-vfolder-ui.h"
  60 #include "mail/message-list.h"
  61 
  62 #include <em-format/e-mail-formatter.h>
  63 #include <em-format/e-mail-parser.h>
  64 #include <em-format/e-mail-part-utils.h>
  65 
  66 #define E_MAIL_READER_GET_PRIVATE(obj) \
  67 	((EMailReaderPrivate *) g_object_get_qdata \
  68 	(G_OBJECT (obj), quark_private))
  69 
  70 #define d(x)
  71 
  72 typedef struct _EMailReaderClosure EMailReaderClosure;
  73 typedef struct _EMailReaderPrivate EMailReaderPrivate;
  74 
  75 struct _EMailReaderClosure {
  76 	EMailReader *reader;
  77 	EActivity *activity;
  78 	gchar *message_uid;
  79 };
  80 
  81 struct _EMailReaderPrivate {
  82 
  83 	EMailForwardStyle forward_style;
  84 	EMailReplyStyle reply_style;
  85 
  86 	/* This timer runs when the user selects a single message. */
  87 	guint message_selected_timeout_id;
  88 
  89 	/* This allows message retrieval to be cancelled if another
  90 	 * message is selected before the retrieval has completed. */
  91 	GCancellable *retrieving_message;
  92 
  93 	/* These flags work together to prevent message selection
  94 	 * restoration after a folder switch from automatically
  95 	 * marking the message as read.  We only want that to
  96 	 * happen when the -user- selects a message. */
  97 	guint folder_was_just_selected    : 1;
  98 	guint restoring_message_selection : 1;
  99 	guint avoid_next_mark_as_seen     : 1;
 100 
 101 	guint group_by_threads : 1;
 102 };
 103 
 104 enum {
 105 	CHANGED,
 106 	FOLDER_LOADED,
 107 	MESSAGE_LOADED,
 108 	MESSAGE_SEEN,
 109 	SHOW_SEARCH_BAR,
 110 	UPDATE_ACTIONS,
 111 	SHOW_FOLDER,
 112 	SHOW_PREVTAB,
 113 	SHOW_NEXTTAB,
 114 	CLOSE_TAB,
 115 	LAST_SIGNAL
 116 };
 117 
 118 /* Remembers the previously selected folder when transferring messages. */
 119 static gchar *default_xfer_messages_uri;
 120 
 121 static GQuark quark_private;
 122 static guint signals[LAST_SIGNAL];
 123 
 124 G_DEFINE_INTERFACE (EMailReader, e_mail_reader, G_TYPE_INITIALLY_UNOWNED)
 125 
 126 static void
 127 mail_reader_set_display_formatter_for_message (EMailReader *reader,
 128                                                EMailDisplay *display,
 129                                                const gchar *message_uid,
 130                                                CamelMimeMessage *message,
 131                                                CamelFolder *folder);
 132 
 133 static void
 134 mail_reader_closure_free (EMailReaderClosure *closure)
 135 {
 136 	if (closure->reader != NULL)
 137 		g_object_unref (closure->reader);
 138 
 139 	if (closure->activity != NULL)
 140 		g_object_unref (closure->activity);
 141 
 142 	g_free (closure->message_uid);
 143 
 144 	g_slice_free (EMailReaderClosure, closure);
 145 }
 146 
 147 static void
 148 mail_reader_private_free (EMailReaderPrivate *priv)
 149 {
 150 	if (priv->message_selected_timeout_id > 0)
 151 		g_source_remove (priv->message_selected_timeout_id);
 152 
 153 	if (priv->retrieving_message != NULL) {
 154 		g_cancellable_cancel (priv->retrieving_message);
 155 		g_object_unref (priv->retrieving_message);
 156 		priv->retrieving_message = 0;
 157 	}
 158 
 159 	g_slice_free (EMailReaderPrivate, priv);
 160 }
 161 
 162 static void
 163 action_mail_add_sender_cb (GtkAction *action,
 164                            EMailReader *reader)
 165 {
 166 	EShell *shell;
 167 	EMailBackend *backend;
 168 	EShellBackend *shell_backend;
 169 	CamelMessageInfo *info = NULL;
 170 	CamelFolder *folder;
 171 	GPtrArray *uids;
 172 	const gchar *address;
 173 	const gchar *message_uid;
 174 
 175 	folder = e_mail_reader_get_folder (reader);
 176 	backend = e_mail_reader_get_backend (reader);
 177 
 178 	uids = e_mail_reader_get_selected_uids (reader);
 179 	g_return_if_fail (uids != NULL && uids->len == 1);
 180 	message_uid = g_ptr_array_index (uids, 0);
 181 
 182 	info = camel_folder_get_message_info (folder, message_uid);
 183 	if (info == NULL)
 184 		goto exit;
 185 
 186 	address = camel_message_info_from (info);
 187 	if (address == NULL || *address == '\0')
 188 		goto exit;
 189 
 190 	/* XXX EBookShellBackend should be listening for this
 191 	 *     event.  Kind of kludgey, but works for now. */
 192 	shell_backend = E_SHELL_BACKEND (backend);
 193 	shell = e_shell_backend_get_shell (shell_backend);
 194 	e_shell_event (shell, "contact-quick-add-email", (gpointer) address);
 195 	emu_remove_from_mail_cache_1 (address);
 196 
 197 exit:
 198 	if (info)
 199 		camel_folder_free_message_info (folder, info);
 200 	em_utils_uids_free (uids);
 201 }
 202 
 203 static void
 204 action_add_to_address_book_cb (GtkAction *action,
 205                                EMailReader *reader)
 206 {
 207 	EShell *shell;
 208 	EMailBackend *backend;
 209 	EShellBackend *shell_backend;
 210 	CamelInternetAddress *cia;
 211 	EWebView *web_view;
 212 	CamelURL *curl;
 213 	const gchar *uri;
 214 	gchar *email;
 215 
 216 	/* This action is defined in EMailDisplay. */
 217 
 218 	backend = e_mail_reader_get_backend (reader);
 219 
 220 	web_view = E_WEB_VIEW (e_mail_reader_get_mail_display (reader));
 221 	if (!web_view)
 222 		return;
 223 
 224 	uri = e_web_view_get_selected_uri (web_view);
 225 	g_return_if_fail (uri != NULL);
 226 
 227 	curl = camel_url_new (uri, NULL);
 228 	g_return_if_fail (curl != NULL);
 229 
 230 	if (curl->path == NULL || *curl->path == '\0')
 231 		goto exit;
 232 
 233 	cia = camel_internet_address_new ();
 234 	if (camel_address_decode (CAMEL_ADDRESS (cia), curl->path) < 0) {
 235 		g_object_unref (cia);
 236 		goto exit;
 237 	}
 238 
 239 	email = camel_address_format (CAMEL_ADDRESS (cia));
 240 
 241 	/* XXX EBookShellBackend should be listening for this
 242 	 *     event.  Kind of kludgey, but works for now. */
 243 	shell_backend = E_SHELL_BACKEND (backend);
 244 	shell = e_shell_backend_get_shell (shell_backend);
 245 	e_shell_event (shell, "contact-quick-add-email", email);
 246 	emu_remove_from_mail_cache_1 (curl->path);
 247 
 248 	g_object_unref (cia);
 249 	g_free (email);
 250 
 251 exit:
 252 	camel_url_free (curl);
 253 }
 254 
 255 static void
 256 attachment_load_finish (EAttachment *attachment,
 257                         GAsyncResult *result,
 258                         GFile *file)
 259 {
 260 	EShell *shell;
 261 	GtkWindow *parent;
 262 
 263 	e_attachment_load_finish (attachment, result, NULL);
 264 
 265 	shell = e_shell_get_default ();
 266 	parent = e_shell_get_active_window (shell);
 267 
 268 	e_attachment_save_async (
 269 		attachment, file, (GAsyncReadyCallback)
 270 		e_attachment_save_handle_error, parent);
 271 
 272 	g_object_unref (file);
 273 }
 274 
 275 static void
 276 action_mail_image_save_cb (GtkAction *action,
 277                            EMailReader *reader)
 278 {
 279 	EMailDisplay *display;
 280 	EWebView *web_view;
 281 	EMailPartList *parts;
 282 	const gchar *image_src;
 283 	CamelMimePart *part;
 284 	EAttachment *attachment;
 285 	GFile *file;
 286 
 287 	display = e_mail_reader_get_mail_display (reader);
 288 	web_view = E_WEB_VIEW (display);
 289 
 290 	if (!E_IS_WEB_VIEW (web_view))
 291 		return;
 292 
 293 	image_src = e_web_view_get_cursor_image_src (web_view);
 294 	if (!image_src)
 295 		return;
 296 
 297 	parts = e_mail_display_get_parts_list (display);
 298 	g_return_if_fail (parts != NULL);
 299 	g_return_if_fail (parts->message != NULL);
 300 
 301 	if (g_str_has_prefix (image_src, "cid:")) {
 302 		part = camel_mime_message_get_part_by_content_id (
 303 			parts->message, image_src + 4);
 304 		g_return_if_fail (part != NULL);
 305 
 306 		g_object_ref (part);
 307 	} else {
 308 		CamelStream *image_stream;
 309 		CamelDataWrapper *dw;
 310 		CamelDataCache *cache;
 311 		const gchar *filename;
 312 		const gchar *user_cache_dir;
 313 
 314                 /* Open cache and find the file there */
 315 		user_cache_dir = e_get_user_cache_dir ();
 316 		cache = camel_data_cache_new (user_cache_dir, NULL);
 317 		image_stream = camel_data_cache_get (cache, "http", image_src, NULL);
 318 		if (!image_stream) {
 319 			g_object_unref (cache);
 320 			return;
 321 		}
 322 
 323 		filename = strrchr (image_src, '/');
 324 		if (filename && strchr (filename, '?'))
 325 			filename = NULL;
 326 		else if (filename)
 327 			filename = filename + 1;
 328 
 329 		part = camel_mime_part_new ();
 330 		if (filename)
 331 			camel_mime_part_set_filename (part, filename);
 332 
 333 		dw = camel_data_wrapper_new ();
 334 		camel_data_wrapper_set_mime_type (
 335 			dw, "application/octet-stream");
 336 		camel_data_wrapper_construct_from_stream_sync (
 337 			dw, image_stream, NULL, NULL);
 338 		camel_medium_set_content (CAMEL_MEDIUM (part), dw);
 339 		g_object_unref (dw);
 340 
 341 		camel_mime_part_set_encoding (
 342 			part, CAMEL_TRANSFER_ENCODING_BASE64);
 343 
 344 		g_object_unref (image_stream);
 345 		g_object_unref (cache);
 346 	}
 347 
 348 	file = e_shell_run_save_dialog (
 349 		e_shell_get_default (),
 350 		_("Save Image"), camel_mime_part_get_filename (part),
 351 		NULL, NULL, NULL);
 352 	if (file == NULL) {
 353 		g_object_unref (part);
 354 		return;
 355 	}
 356 
 357 	attachment = e_attachment_new ();
 358 	e_attachment_set_mime_part (attachment, part);
 359 
 360 	e_attachment_load_async (
 361 		attachment, (GAsyncReadyCallback)
 362 		attachment_load_finish, file);
 363 
 364 	g_object_unref (part);
 365 }
 366 
 367 static void
 368 action_mail_charset_cb (GtkRadioAction *action,
 369                         GtkRadioAction *current,
 370                         EMailReader *reader)
 371 {
 372 	EMailDisplay *display;
 373 	const gchar *charset;
 374 
 375 	if (action != current)
 376 		return;
 377 
 378 	display = e_mail_reader_get_mail_display (reader);
 379 	charset = g_object_get_data (G_OBJECT (action), "charset");
 380 
 381 	/* Charset for "Default" action will be NULL. */
 382 	e_mail_display_set_charset (display, charset);
 383 }
 384 
 385 static void
 386 action_mail_check_for_junk_cb (GtkAction *action,
 387                                EMailReader *reader)
 388 {
 389 	EMailBackend *backend;
 390 	EMailSession *session;
 391 	CamelFolder *folder;
 392 	GPtrArray *uids;
 393 
 394 	folder = e_mail_reader_get_folder (reader);
 395 	backend = e_mail_reader_get_backend (reader);
 396 	uids = e_mail_reader_get_selected_uids (reader);
 397 
 398 	session = e_mail_backend_get_session (backend);
 399 
 400 	mail_filter_folder (
 401 		session, folder, uids,
 402 		E_FILTER_SOURCE_JUNKTEST, FALSE);
 403 }
 404 
 405 static void
 406 action_mail_copy_cb (GtkAction *action,
 407                      EMailReader *reader)
 408 {
 409 	CamelFolder *folder;
 410 	EMailBackend *backend;
 411 	EMailSession *session;
 412 	EMFolderSelector *selector;
 413 	EMFolderTree *folder_tree;
 414 	EMFolderTreeModel *model;
 415 	GtkWidget *dialog;
 416 	GtkWindow *window;
 417 	GPtrArray *uids;
 418 	const gchar *uri;
 419 
 420 	backend = e_mail_reader_get_backend (reader);
 421 	session = e_mail_backend_get_session (backend);
 422 
 423 	folder = e_mail_reader_get_folder (reader);
 424 	window = e_mail_reader_get_window (reader);
 425 	uids = e_mail_reader_get_selected_uids (reader);
 426 
 427 	model = em_folder_tree_model_get_default ();
 428 
 429 	dialog = em_folder_selector_new (
 430 		window, model,
 431 		EM_FOLDER_SELECTOR_CAN_CREATE,
 432 		_("Copy to Folder"), NULL, _("C_opy"));
 433 
 434 	selector = EM_FOLDER_SELECTOR (dialog);
 435 	folder_tree = em_folder_selector_get_folder_tree (selector);
 436 
 437 	em_folder_tree_set_excluded (
 438 		folder_tree,
 439 		EMFT_EXCLUDE_NOSELECT |
 440 		EMFT_EXCLUDE_VIRTUAL |
 441 		EMFT_EXCLUDE_VTRASH);
 442 
 443 	if (default_xfer_messages_uri != NULL)
 444 		em_folder_tree_set_selected (
 445 			folder_tree, default_xfer_messages_uri, FALSE);
 446 
 447 	if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
 448 		goto exit;
 449 
 450 	uri = em_folder_selector_get_selected_uri (selector);
 451 
 452 	g_free (default_xfer_messages_uri);
 453 	default_xfer_messages_uri = g_strdup (uri);
 454 
 455 	if (uri != NULL) {
 456 		mail_transfer_messages (
 457 			session, folder, uids,
 458 			FALSE, uri, 0, NULL, NULL);
 459 		uids = NULL;
 460 	}
 461 
 462 exit:
 463 	if (uids != NULL)
 464 		em_utils_uids_free (uids);
 465 
 466 	gtk_widget_destroy (dialog);
 467 }
 468 
 469 static void
 470 action_mail_delete_cb (GtkAction *action,
 471                        EMailReader *reader)
 472 {
 473 	guint32 mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED;
 474 	guint32 set  = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED;
 475 
 476 	if (!e_mail_reader_confirm_delete (reader))
 477 		return;
 478 
 479 	/* FIXME Verify all selected messages are deletable.
 480 	 *       But handle it by disabling this action. */
 481 
 482 	if (e_mail_reader_mark_selected (reader, mask, set) == 1)
 483 		e_mail_reader_select_next_message (reader, FALSE);
 484 }
 485 
 486 static void
 487 action_mail_filter_on_mailing_list_cb (GtkAction *action,
 488                                        EMailReader *reader)
 489 {
 490 	e_mail_reader_create_filter_from_selected (reader, AUTO_MLIST);
 491 }
 492 
 493 static void
 494 action_mail_filter_on_recipients_cb (GtkAction *action,
 495                                      EMailReader *reader)
 496 {
 497 	e_mail_reader_create_filter_from_selected (reader, AUTO_TO);
 498 }
 499 
 500 static void
 501 action_mail_filter_on_sender_cb (GtkAction *action,
 502                                  EMailReader *reader)
 503 {
 504 	e_mail_reader_create_filter_from_selected (reader, AUTO_FROM);
 505 }
 506 
 507 static void
 508 action_mail_filter_on_subject_cb (GtkAction *action,
 509                                   EMailReader *reader)
 510 {
 511 	e_mail_reader_create_filter_from_selected (reader, AUTO_SUBJECT);
 512 }
 513 
 514 static void
 515 action_mail_filters_apply_cb (GtkAction *action,
 516                               EMailReader *reader)
 517 {
 518 	EMailBackend *backend;
 519 	EMailSession *session;
 520 	CamelFolder *folder;
 521 	GPtrArray *uids;
 522 
 523 	folder = e_mail_reader_get_folder (reader);
 524 	backend = e_mail_reader_get_backend (reader);
 525 	uids = e_mail_reader_get_selected_uids (reader);
 526 
 527 	session = e_mail_backend_get_session (backend);
 528 
 529 	mail_filter_folder (
 530 		session, folder, uids,
 531 		E_FILTER_SOURCE_DEMAND, FALSE);
 532 }
 533 
 534 static void
 535 action_mail_remove_attachments_cb (GtkAction *action,
 536                                    EMailReader *reader)
 537 {
 538 	e_mail_reader_remove_attachments (reader);
 539 }
 540 
 541 static void
 542 action_mail_remove_duplicates_cb (GtkAction *action,
 543                                   EMailReader *reader)
 544 {
 545 	e_mail_reader_remove_duplicates (reader);
 546 }
 547 
 548 static void
 549 action_mail_find_cb (GtkAction *action,
 550                      EMailReader *reader)
 551 {
 552 	e_mail_reader_show_search_bar (reader);
 553 }
 554 
 555 static void
 556 action_mail_flag_clear_cb (GtkAction *action,
 557                            EMailReader *reader)
 558 {
 559 	EMailDisplay *display;
 560 	CamelFolder *folder;
 561 	GtkWindow *window;
 562 	GPtrArray *uids;
 563 
 564 	folder = e_mail_reader_get_folder (reader);
 565 	display = e_mail_reader_get_mail_display (reader);
 566 	uids = e_mail_reader_get_selected_uids (reader);
 567 	window = e_mail_reader_get_window (reader);
 568 
 569 	em_utils_flag_for_followup_clear (window, folder, uids);
 570 
 571 	e_mail_display_reload (display);
 572 }
 573 
 574 static void
 575 action_mail_flag_completed_cb (GtkAction *action,
 576                                EMailReader *reader)
 577 {
 578 	EMailDisplay *display;
 579 	CamelFolder *folder;
 580 	GtkWindow *window;
 581 	GPtrArray *uids;
 582 
 583 	folder = e_mail_reader_get_folder (reader);
 584 	display = e_mail_reader_get_mail_display (reader);
 585 	uids = e_mail_reader_get_selected_uids (reader);
 586 	window = e_mail_reader_get_window (reader);
 587 
 588 	em_utils_flag_for_followup_completed (window, folder, uids);
 589 
 590 	e_mail_display_reload (display);
 591 }
 592 
 593 static void
 594 action_mail_flag_for_followup_cb (GtkAction *action,
 595                                   EMailReader *reader)
 596 {
 597 	CamelFolder *folder;
 598 	GPtrArray *uids;
 599 
 600 	folder = e_mail_reader_get_folder (reader);
 601 	uids = e_mail_reader_get_selected_uids (reader);
 602 
 603 	em_utils_flag_for_followup (reader, folder, uids);
 604 }
 605 
 606 static gboolean
 607 get_close_browser_reader (EMailReader *reader)
 608 {
 609 	GSettings *settings;
 610 	const gchar *key;
 611 	gchar *value;
 612 	gboolean close_it = FALSE;
 613 
 614 	/* only allow closing of a mail browser and nothing else */
 615 	if (!E_IS_MAIL_BROWSER (reader))
 616 		return FALSE;
 617 
 618 	settings = g_settings_new ("org.gnome.evolution.mail");
 619 
 620 	key = "prompt-on-reply-close-browser";
 621 	value = g_settings_get_string (settings, key);
 622 
 623 	if (value && g_str_equal (value, "always")) {
 624 		close_it = TRUE;
 625 	} else if (!value || !g_str_equal (value, "never")) {
 626 		GtkWidget *dialog;
 627 		GtkWindow *parent;
 628 		gint response;
 629 		EShell *shell;
 630 		EMailBackend *backend;
 631 		EShellBackend *shell_backend;
 632 
 633 		backend = e_mail_reader_get_backend (reader);
 634 
 635 		shell_backend = E_SHELL_BACKEND (backend);
 636 		shell = e_shell_backend_get_shell (shell_backend);
 637 
 638 		parent = e_shell_get_active_window (shell);
 639 		if (!parent)
 640 			parent = e_mail_reader_get_window (reader);
 641 
 642 		dialog = e_alert_dialog_new_for_args (
 643 			parent, "mail:ask-reply-close-browser", NULL);
 644 		response = gtk_dialog_run (GTK_DIALOG (dialog));
 645 		gtk_widget_destroy (dialog);
 646 
 647 		close_it = response == GTK_RESPONSE_YES || response == GTK_RESPONSE_OK;
 648 
 649 		if (response == GTK_RESPONSE_OK)
 650 			g_settings_set_string (settings, key, "always");
 651 		else if (response == GTK_RESPONSE_CANCEL)
 652 			g_settings_set_string (settings, key, "never");
 653 	}
 654 
 655 	g_free (value);
 656 	g_object_unref (settings);
 657 
 658 	return close_it;
 659 }
 660 
 661 static void
 662 check_close_browser_reader (EMailReader *reader)
 663 {
 664 	if (get_close_browser_reader (reader))
 665 		gtk_widget_destroy (GTK_WIDGET (reader));
 666 }
 667 
 668 static void
 669 action_mail_forward_cb (GtkAction *action,
 670                         EMailReader *reader)
 671 {
 672 	CamelFolder *folder;
 673 	GtkWindow *window;
 674 	GPtrArray *uids;
 675 	gboolean close_reader;
 676 
 677 	folder = e_mail_reader_get_folder (reader);
 678 	window = e_mail_reader_get_window (reader);
 679 	uids = e_mail_reader_get_selected_uids (reader);
 680 	g_return_if_fail (uids != NULL);
 681 	close_reader = get_close_browser_reader (reader);
 682 
 683 	/* XXX Either e_mail_reader_get_selected_uids()
 684 	 *     or MessageList should do this itself. */
 685 	g_ptr_array_set_free_func (uids, (GDestroyNotify) g_free);
 686 
 687 	if (em_utils_ask_open_many (window, uids->len))
 688 		em_utils_forward_messages (
 689 			reader, folder, uids,
 690 			e_mail_reader_get_forward_style (reader),
 691 			close_reader ? GTK_WIDGET (reader) : NULL);
 692 
 693 	g_ptr_array_unref (uids);
 694 }
 695 
 696 static void
 697 action_mail_forward_attached_cb (GtkAction *action,
 698                                  EMailReader *reader)
 699 {
 700 	CamelFolder *folder;
 701 	GtkWindow *window;
 702 	GPtrArray *uids;
 703 	gboolean close_reader;
 704 
 705 	folder = e_mail_reader_get_folder (reader);
 706 	window = e_mail_reader_get_window (reader);
 707 	uids = e_mail_reader_get_selected_uids (reader);
 708 	g_return_if_fail (uids != NULL);
 709 	close_reader = get_close_browser_reader (reader);
 710 
 711 	/* XXX Either e_mail_reader_get_selected_uids()
 712 	 *     or MessageList should do this itself. */
 713 	g_ptr_array_set_free_func (uids, (GDestroyNotify) g_free);
 714 
 715 	if (em_utils_ask_open_many (window, uids->len))
 716 		em_utils_forward_messages (
 717 			reader, folder, uids,
 718 			E_MAIL_FORWARD_STYLE_ATTACHED,
 719 			close_reader ? GTK_WIDGET (reader) : NULL);
 720 
 721 	g_ptr_array_unref (uids);
 722 }
 723 
 724 static void
 725 action_mail_forward_inline_cb (GtkAction *action,
 726                                EMailReader *reader)
 727 {
 728 	CamelFolder *folder;
 729 	GtkWindow *window;
 730 	GPtrArray *uids;
 731 	gboolean close_reader;
 732 
 733 	folder = e_mail_reader_get_folder (reader);
 734 	window = e_mail_reader_get_window (reader);
 735 	uids = e_mail_reader_get_selected_uids (reader);
 736 	g_return_if_fail (uids != NULL);
 737 	close_reader = get_close_browser_reader (reader);
 738 
 739 	/* XXX Either e_mail_reader_get_selected_uids()
 740 	 *     or MessageList should do this itself. */
 741 	g_ptr_array_set_free_func (uids, (GDestroyNotify) g_free);
 742 
 743 	if (em_utils_ask_open_many (window, uids->len))
 744 		em_utils_forward_messages (
 745 			reader, folder, uids,
 746 			E_MAIL_FORWARD_STYLE_INLINE,
 747 			close_reader ? GTK_WIDGET (reader) : NULL);
 748 
 749 	g_ptr_array_unref (uids);
 750 }
 751 
 752 static void
 753 action_mail_forward_quoted_cb (GtkAction *action,
 754                                EMailReader *reader)
 755 {
 756 	CamelFolder *folder;
 757 	GtkWindow *window;
 758 	GPtrArray *uids;
 759 	gboolean close_reader;
 760 
 761 	folder = e_mail_reader_get_folder (reader);
 762 	window = e_mail_reader_get_window (reader);
 763 	uids = e_mail_reader_get_selected_uids (reader);
 764 	g_return_if_fail (uids != NULL);
 765 	close_reader = get_close_browser_reader (reader);
 766 
 767 	/* XXX Either e_mail_reader_get_selected_uids()
 768 	 *     or MessageList should do this itself. */
 769 	g_ptr_array_set_free_func (uids, (GDestroyNotify) g_free);
 770 
 771 	if (em_utils_ask_open_many (window, uids->len))
 772 		em_utils_forward_messages (
 773 			reader, folder, uids,
 774 			E_MAIL_FORWARD_STYLE_QUOTED,
 775 			close_reader ? GTK_WIDGET (reader) : NULL);
 776 
 777 	g_ptr_array_unref (uids);
 778 }
 779 
 780 static void
 781 action_mail_load_images_cb (GtkAction *action,
 782                             EMailReader *reader)
 783 {
 784 	EMailDisplay *display;
 785 
 786 	display = e_mail_reader_get_mail_display (reader);
 787 
 788 	e_mail_display_load_images (display);
 789 }
 790 
 791 static void
 792 action_mail_mark_important_cb (GtkAction *action,
 793                                EMailReader *reader)
 794 {
 795 	guint32 mask = CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_DELETED;
 796 	guint32 set  = CAMEL_MESSAGE_FLAGGED;
 797 
 798 	e_mail_reader_mark_selected (reader, mask, set);
 799 }
 800 
 801 static gboolean
 802 is_junk_folder_selected (EMailReader *reader)
 803 {
 804 	CamelFolder *folder;
 805 
 806 	folder = e_mail_reader_get_folder (reader);
 807 
 808 	return folder && (folder->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0;
 809 }
 810 
 811 static void
 812 action_mail_mark_junk_cb (GtkAction *action,
 813                           EMailReader *reader)
 814 {
 815 	guint32 mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_JUNK |
 816 		CAMEL_MESSAGE_NOTJUNK | CAMEL_MESSAGE_JUNK_LEARN;
 817 	guint32 set  = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_JUNK |
 818 		CAMEL_MESSAGE_JUNK_LEARN;
 819 
 820 	if (e_mail_reader_mark_selected (reader, mask, set) == 1 &&
 821 	    !is_junk_folder_selected (reader))
 822 		e_mail_reader_select_next_message (reader, TRUE);
 823 }
 824 
 825 static void
 826 action_mail_mark_notjunk_cb (GtkAction *action,
 827                              EMailReader *reader)
 828 {
 829 	guint32 mask = CAMEL_MESSAGE_JUNK | CAMEL_MESSAGE_NOTJUNK |
 830 		CAMEL_MESSAGE_JUNK_LEARN;
 831 	guint32 set  = CAMEL_MESSAGE_NOTJUNK | CAMEL_MESSAGE_JUNK_LEARN;
 832 
 833 	if (e_mail_reader_mark_selected (reader, mask, set) == 1 &&
 834 	    is_junk_folder_selected (reader))
 835 		e_mail_reader_select_next_message (reader, TRUE);
 836 }
 837 
 838 static void
 839 action_mail_mark_read_cb (GtkAction *action,
 840                           EMailReader *reader)
 841 {
 842 	guint32 mask = CAMEL_MESSAGE_SEEN;
 843 	guint32 set  = CAMEL_MESSAGE_SEEN;
 844 
 845 	e_mail_reader_mark_selected (reader, mask, set);
 846 }
 847 
 848 static void
 849 action_mail_mark_unimportant_cb (GtkAction *action,
 850                                  EMailReader *reader)
 851 {
 852 	guint32 mask = CAMEL_MESSAGE_FLAGGED;
 853 	guint32 set  = 0;
 854 
 855 	e_mail_reader_mark_selected (reader, mask, set);
 856 }
 857 
 858 static void
 859 action_mail_mark_unread_cb (GtkAction *action,
 860                             EMailReader *reader)
 861 {
 862 	GtkWidget *message_list;
 863 	EMFolderTreeModel *model;
 864 	CamelFolder *folder;
 865 	guint32 mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED;
 866 	guint32 set  = 0;
 867 	guint n_marked;
 868 
 869 	message_list = e_mail_reader_get_message_list (reader);
 870 
 871 	n_marked = e_mail_reader_mark_selected (reader, mask, set);
 872 
 873 	if (MESSAGE_LIST (message_list)->seen_id != 0) {
 874 		g_source_remove (MESSAGE_LIST (message_list)->seen_id);
 875 		MESSAGE_LIST (message_list)->seen_id = 0;
 876 	}
 877 
 878 	/* Notify the tree model that the user has marked messages as
 879 	 * unread so it doesn't mistake the event as new mail arriving. */
 880 	model = em_folder_tree_model_get_default ();
 881 	folder = e_mail_reader_get_folder (reader);
 882 	em_folder_tree_model_user_marked_unread (model, folder, n_marked);
 883 }
 884 
 885 static void
 886 action_mail_message_edit_cb (GtkAction *action,
 887                              EMailReader *reader)
 888 {
 889 	EShell *shell;
 890 	EMailBackend *backend;
 891 	ESourceRegistry *registry;
 892 	CamelFolder *folder;
 893 	GPtrArray *uids;
 894 	gboolean replace;
 895 
 896 	folder = e_mail_reader_get_folder (reader);
 897 	uids = e_mail_reader_get_selected_uids (reader);
 898 	g_return_if_fail (uids != NULL);
 899 
 900 	backend = e_mail_reader_get_backend (reader);
 901 	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
 902 	registry = e_shell_get_registry (shell);
 903 
 904 	/* XXX Either e_mail_reader_get_selected_uids()
 905 	 *     or MessageList should do this itself. */
 906 	g_ptr_array_set_free_func (uids, (GDestroyNotify) g_free);
 907 
 908 	replace = em_utils_folder_is_drafts (registry, folder);
 909 	em_utils_edit_messages (reader, folder, uids, replace);
 910 
 911 	g_ptr_array_unref (uids);
 912 }
 913 
 914 static void
 915 action_mail_message_new_cb (GtkAction *action,
 916                             EMailReader *reader)
 917 {
 918 	EShell *shell;
 919 	EMailBackend *backend;
 920 	EShellBackend *shell_backend;
 921 	CamelFolder *folder;
 922 
 923 	folder = e_mail_reader_get_folder (reader);
 924 	backend = e_mail_reader_get_backend (reader);
 925 
 926 	shell_backend = E_SHELL_BACKEND (backend);
 927 	shell = e_shell_backend_get_shell (shell_backend);
 928 
 929 	em_utils_compose_new_message (shell, folder);
 930 }
 931 
 932 static void
 933 action_mail_message_open_cb (GtkAction *action,
 934                              EMailReader *reader)
 935 {
 936 	e_mail_reader_open_selected_mail (reader);
 937 }
 938 
 939 static void
 940 action_mail_move_cb (GtkAction *action,
 941                      EMailReader *reader)
 942 {
 943 	CamelFolder *folder;
 944 	EMailBackend *backend;
 945 	EMailSession *session;
 946 	EMFolderSelector *selector;
 947 	EMFolderTree *folder_tree;
 948 	EMFolderTreeModel *model;
 949 	GtkWidget *dialog;
 950 	GtkWindow *window;
 951 	GPtrArray *uids;
 952 	const gchar *uri;
 953 
 954 	backend = e_mail_reader_get_backend (reader);
 955 	session = e_mail_backend_get_session (backend);
 956 
 957 	folder = e_mail_reader_get_folder (reader);
 958 	uids = e_mail_reader_get_selected_uids (reader);
 959 	window = e_mail_reader_get_window (reader);
 960 
 961 	model = em_folder_tree_model_get_default ();
 962 
 963 	dialog = em_folder_selector_new (
 964 		window, model,
 965 		EM_FOLDER_SELECTOR_CAN_CREATE,
 966 		_("Move to Folder"), NULL, _("_Move"));
 967 
 968 	selector = EM_FOLDER_SELECTOR (dialog);
 969 	folder_tree = em_folder_selector_get_folder_tree (selector);
 970 
 971 	em_folder_tree_set_excluded (
 972 		folder_tree,
 973 		EMFT_EXCLUDE_NOSELECT |
 974 		EMFT_EXCLUDE_VIRTUAL |
 975 		EMFT_EXCLUDE_VTRASH);
 976 
 977 	if (default_xfer_messages_uri != NULL)
 978 		em_folder_tree_set_selected (
 979 			folder_tree, default_xfer_messages_uri, FALSE);
 980 
 981 	if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
 982 		goto exit;
 983 
 984 	uri = em_folder_selector_get_selected_uri (selector);
 985 
 986 	g_free (default_xfer_messages_uri);
 987 	default_xfer_messages_uri = g_strdup (uri);
 988 
 989 	if (uri != NULL) {
 990 		mail_transfer_messages (
 991 			session, folder, uids,
 992 			TRUE, uri, 0, NULL, NULL);
 993 		uids = NULL;
 994 	}
 995 
 996 exit:
 997 	if (uids != NULL)
 998 		em_utils_uids_free (uids);
 999 
1000 	gtk_widget_destroy (dialog);
1001 }
1002 
1003 static void
1004 action_mail_folder_cb (GtkAction *action,
1005                        EMailReader *reader)
1006 {
1007 	g_signal_emit (reader, signals[SHOW_FOLDER], 0);
1008 }
1009 
1010 static void
1011 action_mail_nexttab_cb (GtkAction *action,
1012                      EMailReader *reader)
1013 {
1014 	g_signal_emit (reader, signals[SHOW_NEXTTAB], 0);
1015 }
1016 
1017 static void
1018 action_mail_prevtab_cb (GtkAction *action,
1019                      EMailReader *reader)
1020 {
1021 	g_signal_emit (reader, signals[SHOW_PREVTAB], 0);
1022 }
1023 
1024 static void
1025 action_mail_closetab_cb (GtkAction *action,
1026                      EMailReader *reader)
1027 {
1028 	g_signal_emit (reader, signals[CLOSE_TAB], 0);
1029 }
1030 
1031 static void
1032 action_mail_next_cb (GtkAction *action,
1033                      EMailReader *reader)
1034 {
1035 	GtkWidget *message_list;
1036 	MessageListSelectDirection direction;
1037 	guint32 flags, mask;
1038 
1039 	direction = MESSAGE_LIST_SELECT_NEXT;
1040 	flags = 0;
1041 	mask  = 0;
1042 
1043 	message_list = e_mail_reader_get_message_list (reader);
1044 
1045 	message_list_select (
1046 		MESSAGE_LIST (message_list), direction, flags, mask);
1047 }
1048 
1049 static void
1050 action_mail_next_important_cb (GtkAction *action,
1051                                EMailReader *reader)
1052 {
1053 	GtkWidget *message_list;
1054 	MessageListSelectDirection direction;
1055 	guint32 flags, mask;
1056 
1057 	direction = MESSAGE_LIST_SELECT_NEXT | MESSAGE_LIST_SELECT_WRAP;
1058 	flags = CAMEL_MESSAGE_FLAGGED;
1059 	mask  = CAMEL_MESSAGE_FLAGGED;
1060 
1061 	message_list = e_mail_reader_get_message_list (reader);
1062 
1063 	message_list_select (
1064 		MESSAGE_LIST (message_list), direction, flags, mask);
1065 }
1066 
1067 static void
1068 action_mail_next_thread_cb (GtkAction *action,
1069                             EMailReader *reader)
1070 {
1071 	GtkWidget *message_list;
1072 
1073 	message_list = e_mail_reader_get_message_list (reader);
1074 
1075 	message_list_select_next_thread (MESSAGE_LIST (message_list));
1076 }
1077 
1078 static void
1079 action_mail_next_unread_cb (GtkAction *action,
1080                             EMailReader *reader)
1081 {
1082 	GtkWidget *message_list;
1083 	MessageListSelectDirection direction;
1084 	guint32 flags, mask;
1085 
1086 	direction = MESSAGE_LIST_SELECT_NEXT | MESSAGE_LIST_SELECT_WRAP;
1087 	flags = 0;
1088 	mask  = CAMEL_MESSAGE_SEEN;
1089 
1090 	message_list = e_mail_reader_get_message_list (reader);
1091 
1092 	message_list_select (
1093 		MESSAGE_LIST (message_list), direction, flags, mask);
1094 }
1095 
1096 static void
1097 action_mail_previous_cb (GtkAction *action,
1098                          EMailReader *reader)
1099 {
1100 	GtkWidget *message_list;
1101 	MessageListSelectDirection direction;
1102 	guint32 flags, mask;
1103 
1104 	direction = MESSAGE_LIST_SELECT_PREVIOUS;
1105 	flags = 0;
1106 	mask  = 0;
1107 
1108 	message_list = e_mail_reader_get_message_list (reader);
1109 
1110 	message_list_select (
1111 		MESSAGE_LIST (message_list), direction, flags, mask);
1112 }
1113 
1114 static void
1115 action_mail_previous_important_cb (GtkAction *action,
1116                                    EMailReader *reader)
1117 {
1118 	GtkWidget *message_list;
1119 	MessageListSelectDirection direction;
1120 	guint32 flags, mask;
1121 
1122 	direction = MESSAGE_LIST_SELECT_PREVIOUS | MESSAGE_LIST_SELECT_WRAP;
1123 	flags = CAMEL_MESSAGE_FLAGGED;
1124 	mask  = CAMEL_MESSAGE_FLAGGED;
1125 
1126 	message_list = e_mail_reader_get_message_list (reader);
1127 
1128 	message_list_select (
1129 		MESSAGE_LIST (message_list), direction, flags, mask);
1130 }
1131 
1132 static void
1133 action_mail_previous_thread_cb (GtkAction *action,
1134                             EMailReader *reader)
1135 {
1136 	GtkWidget *message_list;
1137 
1138 	message_list = e_mail_reader_get_message_list (reader);
1139 
1140 	message_list_select_prev_thread (MESSAGE_LIST (message_list));
1141 }
1142 
1143 static void
1144 action_mail_previous_unread_cb (GtkAction *action,
1145                                 EMailReader *reader)
1146 {
1147 	GtkWidget *message_list;
1148 	MessageListSelectDirection direction;
1149 	guint32 flags, mask;
1150 
1151 	direction = MESSAGE_LIST_SELECT_PREVIOUS | MESSAGE_LIST_SELECT_WRAP;
1152 	flags = 0;
1153 	mask  = CAMEL_MESSAGE_SEEN;
1154 
1155 	message_list = e_mail_reader_get_message_list (reader);
1156 
1157 	message_list_select (
1158 		MESSAGE_LIST (message_list), direction, flags, mask);
1159 }
1160 
1161 static void
1162 action_mail_print_cb (GtkAction *action,
1163                       EMailReader *reader)
1164 {
1165 	GtkPrintOperationAction print_action;
1166 
1167 	print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;
1168 	e_mail_reader_print (reader, print_action);
1169 }
1170 
1171 static void
1172 action_mail_print_preview_cb (GtkAction *action,
1173                               EMailReader *reader)
1174 {
1175 	GtkPrintOperationAction print_action;
1176 
1177 	print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW;
1178 	e_mail_reader_print (reader, print_action);
1179 }
1180 
1181 static void
1182 mail_reader_redirect_cb (CamelFolder *folder,
1183                          GAsyncResult *result,
1184                          EMailReaderClosure *closure)
1185 {
1186 	EShell *shell;
1187 	EMailBackend *backend;
1188 	EAlertSink *alert_sink;
1189 	CamelMimeMessage *message;
1190 	GError *error = NULL;
1191 
1192 	alert_sink = e_activity_get_alert_sink (closure->activity);
1193 
1194 	message = camel_folder_get_message_finish (folder, result, &error);
1195 
1196 	if (e_activity_handle_cancellation (closure->activity, error)) {
1197 		g_warn_if_fail (message == NULL);
1198 		mail_reader_closure_free (closure);
1199 		g_error_free (error);
1200 		return;
1201 
1202 	} else if (error != NULL) {
1203 		g_warn_if_fail (message == NULL);
1204 		e_alert_submit (
1205 			alert_sink, "mail:no-retrieve-message",
1206 			error->message, NULL);
1207 		mail_reader_closure_free (closure);
1208 		g_error_free (error);
1209 		return;
1210 	}
1211 
1212 	g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
1213 
1214 	backend = e_mail_reader_get_backend (closure->reader);
1215 	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
1216 
1217 	em_utils_redirect_message (shell, message);
1218 	check_close_browser_reader (closure->reader);
1219 
1220 	g_object_unref (message);
1221 
1222 	mail_reader_closure_free (closure);
1223 }
1224 
1225 static void
1226 action_mail_redirect_cb (GtkAction *action,
1227                          EMailReader *reader)
1228 {
1229 	EActivity *activity;
1230 	GCancellable *cancellable;
1231 	EMailReaderClosure *closure;
1232 	GtkWidget *message_list;
1233 	CamelFolder *folder;
1234 	const gchar *message_uid;
1235 
1236 	folder = e_mail_reader_get_folder (reader);
1237 	message_list = e_mail_reader_get_message_list (reader);
1238 
1239 	message_uid = MESSAGE_LIST (message_list)->cursor_uid;
1240 	g_return_if_fail (message_uid != NULL);
1241 
1242 	/* Open the message asynchronously. */
1243 
1244 	activity = e_mail_reader_new_activity (reader);
1245 	cancellable = e_activity_get_cancellable (activity);
1246 
1247 	closure = g_slice_new0 (EMailReaderClosure);
1248 	closure->activity = activity;
1249 	closure->reader = g_object_ref (reader);
1250 
1251 	camel_folder_get_message (
1252 		folder, message_uid, G_PRIORITY_DEFAULT,
1253 		cancellable, (GAsyncReadyCallback)
1254 		mail_reader_redirect_cb, closure);
1255 }
1256 
1257 static void
1258 action_mail_reply_all_check (CamelFolder *folder,
1259                              GAsyncResult *result,
1260                              EMailReaderClosure *closure)
1261 {
1262 	EAlertSink *alert_sink;
1263 	CamelMimeMessage *message;
1264 	CamelInternetAddress *to, *cc;
1265 	gint recip_count = 0;
1266 	EMailReplyType type = E_MAIL_REPLY_TO_ALL;
1267 	GError *error = NULL;
1268 
1269 	alert_sink = e_activity_get_alert_sink (closure->activity);
1270 
1271 	message = camel_folder_get_message_finish (folder, result, &error);
1272 
1273 	if (e_activity_handle_cancellation (closure->activity, error)) {
1274 		g_warn_if_fail (message == NULL);
1275 		mail_reader_closure_free (closure);
1276 		g_error_free (error);
1277 		return;
1278 
1279 	} else if (error != NULL) {
1280 		g_warn_if_fail (message == NULL);
1281 		e_alert_submit (
1282 			alert_sink, "mail:no-retrieve-message",
1283 			error->message, NULL);
1284 		mail_reader_closure_free (closure);
1285 		g_error_free (error);
1286 		return;
1287 	}
1288 
1289 	g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
1290 
1291 	to = camel_mime_message_get_recipients (
1292 		message, CAMEL_RECIPIENT_TYPE_TO);
1293 	cc = camel_mime_message_get_recipients (
1294 		message, CAMEL_RECIPIENT_TYPE_CC);
1295 
1296 	recip_count = camel_address_length (CAMEL_ADDRESS (to));
1297 	recip_count += camel_address_length (CAMEL_ADDRESS (cc));
1298 
1299 	if (recip_count >= 15) {
1300 		GtkWidget *dialog;
1301 		GtkWidget *check;
1302 		GtkWidget *container;
1303 		gint response;
1304 
1305 		dialog = e_alert_dialog_new_for_args (
1306 			e_mail_reader_get_window (closure->reader),
1307 			"mail:ask-reply-many-recips", NULL);
1308 
1309 		container = e_alert_dialog_get_content_area (
1310 			E_ALERT_DIALOG (dialog));
1311 
1312 		/* Check buttons */
1313 		check = gtk_check_button_new_with_mnemonic (
1314 			_("_Do not ask me again."));
1315 		gtk_box_pack_start (
1316 			GTK_BOX (container), check, FALSE, FALSE, 0);
1317 		gtk_widget_show (check);
1318 
1319 		response = gtk_dialog_run (GTK_DIALOG (dialog));
1320 
1321 		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check))) {
1322 			GSettings *settings;
1323 
1324 			settings = g_settings_new ("org.gnome.evolution.mail");
1325 			g_settings_set_boolean (settings, "prompt-on-reply-many-recips", FALSE);
1326 			g_object_unref (settings);
1327 		}
1328 
1329 		gtk_widget_destroy (dialog);
1330 
1331 		switch (response) {
1332 			case GTK_RESPONSE_NO:
1333 				type = E_MAIL_REPLY_TO_SENDER;
1334 				break;
1335 			case GTK_RESPONSE_CANCEL:
1336 			case GTK_RESPONSE_DELETE_EVENT:
1337 				goto exit;
1338 			default:
1339 				break;
1340 		}
1341 	}
1342 
1343 	e_mail_reader_reply_to_message (closure->reader, message, type);
1344 	check_close_browser_reader (closure->reader);
1345 
1346 exit:
1347 	g_object_unref (message);
1348 
1349 	mail_reader_closure_free (closure);
1350 }
1351 
1352 static void
1353 action_mail_reply_all_cb (GtkAction *action,
1354                           EMailReader *reader)
1355 {
1356 	GSettings *settings;
1357 	const gchar *key;
1358 	guint32 state;
1359 	gboolean ask;
1360 
1361 	state = e_mail_reader_check_state (reader);
1362 
1363 	settings = g_settings_new ("org.gnome.evolution.mail");
1364 	key = "prompt-on-reply-many-recips";
1365 	ask = g_settings_get_boolean (settings, key);
1366 	g_object_unref (settings);
1367 
1368 	if (ask && !(state & E_MAIL_READER_SELECTION_IS_MAILING_LIST)) {
1369 		EActivity *activity;
1370 		GCancellable *cancellable;
1371 		EMailReaderClosure *closure;
1372 		CamelFolder *folder;
1373 		GtkWidget *message_list;
1374 		const gchar *message_uid;
1375 
1376 		folder = e_mail_reader_get_folder (reader);
1377 		g_return_if_fail (CAMEL_IS_FOLDER (folder));
1378 
1379 		message_list = e_mail_reader_get_message_list (reader);
1380 		message_uid = MESSAGE_LIST (message_list)->cursor_uid;
1381 		g_return_if_fail (message_uid != NULL);
1382 
1383 		activity = e_mail_reader_new_activity (reader);
1384 		cancellable = e_activity_get_cancellable (activity);
1385 
1386 		closure = g_slice_new0 (EMailReaderClosure);
1387 		closure->activity = activity;
1388 		closure->reader = g_object_ref (reader);
1389 
1390 		camel_folder_get_message (
1391 			folder, message_uid, G_PRIORITY_DEFAULT,
1392 			cancellable, (GAsyncReadyCallback)
1393 			action_mail_reply_all_check, closure);
1394 
1395 		return;
1396 	}
1397 
1398 	e_mail_reader_reply_to_message (reader, NULL, E_MAIL_REPLY_TO_ALL);
1399 	check_close_browser_reader (reader);
1400 }
1401 
1402 static void
1403 action_mail_reply_group_cb (GtkAction *action,
1404                             EMailReader *reader)
1405 {
1406 	GSettings *settings;
1407 	gboolean reply_list;
1408 	guint32 state;
1409 
1410 	state = e_mail_reader_check_state (reader);
1411 
1412 	settings = g_settings_new ("org.gnome.evolution.mail");
1413 	reply_list = g_settings_get_boolean (settings, "composer-group-reply-to-list");
1414 	g_object_unref (settings);
1415 
1416 	if (reply_list && (state & E_MAIL_READER_SELECTION_IS_MAILING_LIST)) {
1417 		e_mail_reader_reply_to_message (
1418 			reader, NULL, E_MAIL_REPLY_TO_LIST);
1419 		check_close_browser_reader (reader);
1420 	} else
1421 		action_mail_reply_all_cb (action, reader);
1422 }
1423 
1424 static void
1425 action_mail_reply_list_cb (GtkAction *action,
1426                            EMailReader *reader)
1427 {
1428 	e_mail_reader_reply_to_message (reader, NULL, E_MAIL_REPLY_TO_LIST);
1429 	check_close_browser_reader (reader);
1430 }
1431 
1432 static void
1433 action_mail_reply_sender_check (CamelFolder *folder,
1434                                 GAsyncResult *result,
1435                                 EMailReaderClosure *closure)
1436 {
1437 	EAlertSink *alert_sink;
1438 	CamelMimeMessage *message;
1439 	EMailReplyType type = E_MAIL_REPLY_TO_SENDER;
1440 	GSettings *settings;
1441 	gboolean ask_ignore_list_reply_to;
1442 	gboolean ask_list_reply_to;
1443 	gboolean munged_list_message;
1444 	gboolean active;
1445 	GError *error = NULL;
1446 
1447 	alert_sink = e_activity_get_alert_sink (closure->activity);
1448 
1449 	message = camel_folder_get_message_finish (folder, result, &error);
1450 
1451 	if (e_activity_handle_cancellation (closure->activity, error)) {
1452 		g_warn_if_fail (message == NULL);
1453 		mail_reader_closure_free (closure);
1454 		g_error_free (error);
1455 		return;
1456 
1457 	} else if (error != NULL) {
1458 		g_warn_if_fail (message == NULL);
1459 		e_alert_submit (
1460 			alert_sink, "mail:no-retrieve-message",
1461 			error->message, NULL);
1462 		mail_reader_closure_free (closure);
1463 		g_error_free (error);
1464 		return;
1465 	}
1466 
1467 	g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
1468 
1469 	settings = g_settings_new ("org.gnome.evolution.mail");
1470 
1471 	ask_ignore_list_reply_to = g_settings_get_boolean (
1472 		settings, "composer-ignore-list-reply-to");
1473 	ask_list_reply_to = g_settings_get_boolean (
1474 		settings, "prompt-on-list-reply-to");
1475 
1476 	munged_list_message = em_utils_is_munged_list_message (message);
1477 
1478 	/* Don't do the "Are you sure you want to reply in private?" pop-up
1479 	 * if it's a Reply-To: munged list message... unless we're ignoring
1480 	 * munging. */
1481 	if (ask_ignore_list_reply_to || !munged_list_message) {
1482 		GtkWidget *dialog;
1483 		GtkWidget *check;
1484 		GtkWidget *container;
1485 		gint response;
1486 
1487 		dialog = e_alert_dialog_new_for_args (
1488 			e_mail_reader_get_window (closure->reader),
1489 			"mail:ask-list-private-reply", NULL);
1490 
1491 		container = e_alert_dialog_get_content_area (
1492 			E_ALERT_DIALOG (dialog));
1493 
1494 		/* Check buttons */
1495 		check = gtk_check_button_new_with_mnemonic (
1496 			_("_Do not ask me again."));
1497 		gtk_box_pack_start (
1498 			GTK_BOX (container), check, FALSE, FALSE, 0);
1499 		gtk_widget_show (check);
1500 
1501 		response = gtk_dialog_run (GTK_DIALOG (dialog));
1502 
1503 		active = gtk_toggle_button_get_active (
1504 			GTK_TOGGLE_BUTTON (check));
1505 		if (active) {
1506 			g_settings_set_boolean (
1507 				settings, "prompt-on-private-list-reply", FALSE);
1508 		}
1509 
1510 		gtk_widget_destroy (dialog);
1511 
1512 		if (response == GTK_RESPONSE_YES)
1513 			type = E_MAIL_REPLY_TO_ALL;
1514 		else if (response == GTK_RESPONSE_OK)
1515 			type = E_MAIL_REPLY_TO_LIST;
1516 		else if (response == GTK_RESPONSE_CANCEL ||
1517 			response == GTK_RESPONSE_DELETE_EVENT) {
1518 			goto exit;
1519 		}
1520 
1521 	} else if (ask_list_reply_to) {
1522 		GtkWidget *dialog;
1523 		GtkWidget *container;
1524 		GtkWidget *check_again;
1525 		GtkWidget *check_always_ignore;
1526 		gint response;
1527 
1528 		dialog = e_alert_dialog_new_for_args (
1529 			e_mail_reader_get_window (closure->reader),
1530 			"mail:ask-list-honour-reply-to", NULL);
1531 
1532 		container = e_alert_dialog_get_content_area (
1533 			E_ALERT_DIALOG (dialog));
1534 
1535 		check_again = gtk_check_button_new_with_mnemonic (
1536 			_("_Do not ask me again."));
1537 		gtk_box_pack_start (
1538 			GTK_BOX (container), check_again, FALSE, FALSE, 0);
1539 		gtk_widget_show (check_again);
1540 
1541 		check_always_ignore = gtk_check_button_new_with_mnemonic (
1542 			_("_Always ignore Reply-To: for mailing lists."));
1543 		gtk_box_pack_start (
1544 			GTK_BOX (container), check_always_ignore,
1545 			FALSE, FALSE, 0);
1546 		gtk_widget_show (check_always_ignore);
1547 
1548 		response = gtk_dialog_run (GTK_DIALOG (dialog));
1549 
1550 		active = gtk_toggle_button_get_active (
1551 			GTK_TOGGLE_BUTTON (check_again));
1552 		if (active) {
1553 			g_settings_set_boolean (
1554 				settings, "prompt-on-list-reply-to", FALSE);
1555 		}
1556 
1557 		active = gtk_toggle_button_get_active (
1558 			GTK_TOGGLE_BUTTON (check_always_ignore));
1559 		g_settings_set_boolean (
1560 			settings, "composer-ignore-list-reply-to", active);
1561 
1562 		gtk_widget_destroy (dialog);
1563 
1564 		switch (response) {
1565 			case GTK_RESPONSE_NO:
1566 				type = E_MAIL_REPLY_TO_FROM;
1567 				break;
1568 			case GTK_RESPONSE_OK:
1569 				type = E_MAIL_REPLY_TO_LIST;
1570 				break;
1571 			case GTK_RESPONSE_CANCEL:
1572 			case GTK_RESPONSE_DELETE_EVENT:
1573 				goto exit;
1574 			default:
1575 				break;
1576 		}
1577 	}
1578 
1579 	e_mail_reader_reply_to_message (closure->reader, message, type);
1580 	check_close_browser_reader (closure->reader);
1581 
1582 exit:
1583 	g_object_unref (settings);
1584 	g_object_unref (message);
1585 
1586 	mail_reader_closure_free (closure);
1587 }
1588 
1589 static void
1590 action_mail_reply_sender_cb (GtkAction *action,
1591                              EMailReader *reader)
1592 {
1593 	GSettings *settings;
1594 	gboolean ask_list_reply_to;
1595 	gboolean ask_private_list_reply;
1596 	gboolean ask;
1597 	guint32 state;
1598 
1599 	state = e_mail_reader_check_state (reader);
1600 
1601 	settings = g_settings_new ("org.gnome.evolution.mail");
1602 	ask_list_reply_to = g_settings_get_boolean (
1603 		settings, "prompt-on-list-reply-to");
1604 	ask_private_list_reply = g_settings_get_boolean (
1605 		settings, "prompt-on-private-list-reply");
1606 	g_object_unref (settings);
1607 
1608 	ask = (ask_private_list_reply || ask_list_reply_to);
1609 
1610 	if (ask && (state & E_MAIL_READER_SELECTION_IS_MAILING_LIST)) {
1611 		EActivity *activity;
1612 		GCancellable *cancellable;
1613 		EMailReaderClosure *closure;
1614 		CamelFolder *folder;
1615 		GtkWidget *message_list;
1616 		const gchar *message_uid;
1617 
1618 		folder = e_mail_reader_get_folder (reader);
1619 		g_return_if_fail (CAMEL_IS_FOLDER (folder));
1620 
1621 		message_list = e_mail_reader_get_message_list (reader);
1622 		message_uid = MESSAGE_LIST (message_list)->cursor_uid;
1623 		g_return_if_fail (message_uid != NULL);
1624 
1625 		activity = e_mail_reader_new_activity (reader);
1626 		cancellable = e_activity_get_cancellable (activity);
1627 
1628 		closure = g_slice_new0 (EMailReaderClosure);
1629 		closure->activity = activity;
1630 		closure->reader = g_object_ref (reader);
1631 
1632 		camel_folder_get_message (
1633 			folder, message_uid, G_PRIORITY_DEFAULT,
1634 			cancellable, (GAsyncReadyCallback)
1635 			action_mail_reply_sender_check, closure);
1636 
1637 		return;
1638 	}
1639 
1640 	e_mail_reader_reply_to_message (reader, NULL, E_MAIL_REPLY_TO_SENDER);
1641 	check_close_browser_reader (reader);
1642 }
1643 
1644 static void
1645 action_mail_reply_recipient_cb (GtkAction *action,
1646                                 EMailReader *reader)
1647 {
1648 	e_mail_reader_reply_to_message (reader, NULL, E_MAIL_REPLY_TO_RECIPIENT);
1649 	check_close_browser_reader (reader);
1650 }
1651 
1652 static void
1653 action_mail_save_as_cb (GtkAction *action,
1654                         EMailReader *reader)
1655 {
1656 	e_mail_reader_save_messages (reader);
1657 }
1658 
1659 static void
1660 action_mail_search_folder_from_mailing_list_cb (GtkAction *action,
1661                                                 EMailReader *reader)
1662 {
1663 	e_mail_reader_create_vfolder_from_selected (reader, AUTO_MLIST);
1664 }
1665 
1666 static void
1667 action_mail_search_folder_from_recipients_cb (GtkAction *action,
1668                                               EMailReader *reader)
1669 {
1670 	e_mail_reader_create_vfolder_from_selected (reader, AUTO_TO);
1671 }
1672 
1673 static void
1674 action_mail_search_folder_from_sender_cb (GtkAction *action,
1675                                           EMailReader *reader)
1676 {
1677 	e_mail_reader_create_vfolder_from_selected (reader, AUTO_FROM);
1678 }
1679 
1680 static void
1681 action_mail_search_folder_from_subject_cb (GtkAction *action,
1682                                            EMailReader *reader)
1683 {
1684 	e_mail_reader_create_vfolder_from_selected (reader, AUTO_SUBJECT);
1685 }
1686 
1687 static void
1688 action_mail_show_all_headers_cb (GtkToggleAction *action,
1689                                  EMailReader *reader)
1690 {
1691 	EMailDisplay *display;
1692 
1693 	display = e_mail_reader_get_mail_display (reader);
1694 
1695 	/* mode change when viewing message source is ignored */
1696 	if (e_mail_display_get_mode (display) == E_MAIL_FORMATTER_MODE_SOURCE ||
1697 	    e_mail_display_get_mode (display) == E_MAIL_FORMATTER_MODE_RAW)
1698 		return;
1699 
1700 	if (gtk_toggle_action_get_active (action))
1701 		e_mail_display_set_mode (display, E_MAIL_FORMATTER_MODE_ALL_HEADERS);
1702 	else
1703 		e_mail_display_set_mode (display, E_MAIL_FORMATTER_MODE_NORMAL);
1704 }
1705 
1706 struct _source_retrieval_closure {
1707 	EMailReader *browser;
1708 	EActivity *activity;
1709 	gchar *message_uid;
1710 };
1711 
1712 static void
1713 mail_source_retrieved (GObject *object,
1714                        GAsyncResult *result,
1715                        gpointer user_data)
1716 {
1717 	CamelMimeMessage *message;
1718 	EMailDisplay *display;
1719 	GError *error = NULL;
1720 	struct _source_retrieval_closure *data;
1721 
1722 	data = user_data;
1723 	display = e_mail_reader_get_mail_display (data->browser);
1724 
1725 	message = camel_folder_get_message_finish (
1726 		CAMEL_FOLDER (object), result, &error);
1727 
1728 	/* Sanity check. */
1729 	g_return_if_fail (
1730 		((message != NULL) && (error == NULL)) ||
1731 		((message == NULL) && (error != NULL)));
1732 
1733 	if (error != NULL) {
1734 		gchar *status;
1735 		status = g_strdup_printf (
1736 			"%s<br>%s",
1737 			_("Failed to retrieve message:"),
1738 			error->message);
1739 		e_mail_display_set_status (display, status);
1740 		g_error_free (error);
1741 		g_free (status);
1742 		goto free_data;
1743 	}
1744 
1745 	mail_reader_set_display_formatter_for_message (
1746 		data->browser, display, data->message_uid,
1747 		message, CAMEL_FOLDER (object));
1748 
1749  free_data:
1750 	e_activity_set_state (data->activity, E_ACTIVITY_COMPLETED);
1751 	g_object_unref (data->browser);
1752 	g_object_unref (data->activity);
1753 	g_free (data->message_uid);
1754 	g_free (data);
1755 }
1756 
1757 static void
1758 action_mail_show_source_cb (GtkAction *action,
1759                             EMailReader *reader)
1760 {
1761 	EMailDisplay *display;
1762 	EMailBackend *backend;
1763 	GtkWidget *browser;
1764 	CamelFolder *folder;
1765 	GPtrArray *uids;
1766 	const gchar *message_uid;
1767 	gchar *string;
1768 	EActivity *activity;
1769 	GCancellable *cancellable;
1770 	struct _source_retrieval_closure *closure;
1771 
1772 	backend = e_mail_reader_get_backend (reader);
1773 	folder = e_mail_reader_get_folder (reader);
1774 	uids = e_mail_reader_get_selected_uids (reader);
1775 	g_return_if_fail (uids != NULL && uids->len == 1);
1776 	message_uid = g_ptr_array_index (uids, 0);
1777 
1778 	browser = e_mail_browser_new (backend, NULL, NULL, E_MAIL_FORMATTER_MODE_SOURCE);
1779 	e_mail_reader_set_folder (E_MAIL_READER (browser), folder);
1780 	e_mail_reader_set_message (E_MAIL_READER (browser), message_uid);
1781 	display = e_mail_reader_get_mail_display (E_MAIL_READER (browser));
1782 
1783 	string = g_strdup_printf (_("Retrieving message '%s'"), message_uid);
1784 	e_mail_display_set_parts_list (display, NULL);
1785 	e_mail_display_set_status (display, string);
1786 	gtk_widget_show (browser);
1787 
1788 	activity = e_mail_reader_new_activity (reader);
1789 	e_activity_set_text (activity, string);
1790 	cancellable = e_activity_get_cancellable (activity);
1791 	g_free (string);
1792 
1793 	closure = g_new0 (struct _source_retrieval_closure, 1);
1794 	closure->browser = g_object_ref (E_MAIL_READER (browser));
1795 	closure->activity = activity;
1796 	closure->message_uid = g_strdup (message_uid);
1797 	camel_folder_get_message (
1798 		folder, message_uid, G_PRIORITY_DEFAULT,
1799 		cancellable, mail_source_retrieved,
1800 		closure);
1801 
1802 	em_utils_uids_free (uids);
1803 }
1804 
1805 static void
1806 action_mail_toggle_important_cb (GtkAction *action,
1807                                  EMailReader *reader)
1808 {
1809 	CamelFolder *folder;
1810 	GPtrArray *uids;
1811 	guint ii;
1812 
1813 	folder = e_mail_reader_get_folder (reader);
1814 	uids = e_mail_reader_get_selected_uids (reader);
1815 
1816 	camel_folder_freeze (folder);
1817 
1818 	for (ii = 0; ii < uids->len; ii++) {
1819 		guint32 flags;
1820 
1821 		flags = camel_folder_get_message_flags (
1822 			folder, uids->pdata[ii]);
1823 		flags ^= CAMEL_MESSAGE_FLAGGED;
1824 		if (flags & CAMEL_MESSAGE_FLAGGED)
1825 			flags &= ~CAMEL_MESSAGE_DELETED;
1826 
1827 		camel_folder_set_message_flags (
1828 			folder, uids->pdata[ii], CAMEL_MESSAGE_FLAGGED |
1829 			CAMEL_MESSAGE_DELETED, flags);
1830 	}
1831 
1832 	camel_folder_thaw (folder);
1833 
1834 	em_utils_uids_free (uids);
1835 }
1836 
1837 static void
1838 action_mail_undelete_cb (GtkAction *action,
1839                          EMailReader *reader)
1840 {
1841 	guint32 mask = CAMEL_MESSAGE_DELETED;
1842 	guint32 set  = 0;
1843 
1844 	e_mail_reader_mark_selected (reader, mask, set);
1845 }
1846 
1847 static void
1848 action_mail_zoom_100_cb (GtkAction *action,
1849                          EMailReader *reader)
1850 {
1851 	EMailDisplay *display;
1852 
1853 	display = e_mail_reader_get_mail_display (reader);
1854 
1855 	webkit_web_view_set_zoom_level (WEBKIT_WEB_VIEW (display), 1.0);
1856 }
1857 
1858 static void
1859 action_mail_zoom_in_cb (GtkAction *action,
1860                         EMailReader *reader)
1861 {
1862 	EMailDisplay *display;
1863 
1864 	display = e_mail_reader_get_mail_display (reader);
1865 
1866 	webkit_web_view_zoom_in (WEBKIT_WEB_VIEW (display));
1867 }
1868 
1869 static void
1870 action_mail_zoom_out_cb (GtkAction *action,
1871                          EMailReader *reader)
1872 {
1873 	EMailDisplay *display;
1874 
1875 	display = e_mail_reader_get_mail_display (reader);
1876 
1877 	webkit_web_view_zoom_out (WEBKIT_WEB_VIEW (display));
1878 }
1879 
1880 static void
1881 action_search_folder_recipient_cb (GtkAction *action,
1882                                    EMailReader *reader)
1883 {
1884 	EMailBackend *backend;
1885 	EMailSession *session;
1886 	EWebView *web_view;
1887 	CamelFolder *folder;
1888 	CamelURL *curl;
1889 	const gchar *uri;
1890 
1891 	/* This action is defined in EMailDisplay. */
1892 
1893 	folder = e_mail_reader_get_folder (reader);
1894 	web_view = E_WEB_VIEW (e_mail_reader_get_mail_display (reader));
1895 
1896 	uri = e_web_view_get_selected_uri (web_view);
1897 	g_return_if_fail (uri != NULL);
1898 
1899 	curl = camel_url_new (uri, NULL);
1900 	g_return_if_fail (curl != NULL);
1901 
1902 	backend = e_mail_reader_get_backend (reader);
1903 	session = e_mail_backend_get_session (backend);
1904 
1905 	if (curl->path != NULL && *curl->path != '\0') {
1906 		CamelInternetAddress *inet_addr;
1907 
1908 		inet_addr = camel_internet_address_new ();
1909 		camel_address_decode (CAMEL_ADDRESS (inet_addr), curl->path);
1910 		vfolder_gui_add_from_address (
1911 			session, inet_addr, AUTO_TO, folder);
1912 		g_object_unref (inet_addr);
1913 	}
1914 
1915 	camel_url_free (curl);
1916 }
1917 
1918 static void
1919 action_search_folder_sender_cb (GtkAction *action,
1920                                 EMailReader *reader)
1921 {
1922 	EMailBackend *backend;
1923 	EMailSession *session;
1924 	EWebView *web_view;
1925 	CamelFolder *folder;
1926 	CamelURL *curl;
1927 	const gchar *uri;
1928 
1929 	/* This action is defined in EMailDisplay. */
1930 
1931 	folder = e_mail_reader_get_folder (reader);
1932 	web_view = E_WEB_VIEW (e_mail_reader_get_mail_display (reader));
1933 
1934 	uri = e_web_view_get_selected_uri (web_view);
1935 	g_return_if_fail (uri != NULL);
1936 
1937 	curl = camel_url_new (uri, NULL);
1938 	g_return_if_fail (curl != NULL);
1939 
1940 	backend = e_mail_reader_get_backend (reader);
1941 	session = e_mail_backend_get_session (backend);
1942 
1943 	if (curl->path != NULL && *curl->path != '\0') {
1944 		CamelInternetAddress *inet_addr;
1945 
1946 		inet_addr = camel_internet_address_new ();
1947 		camel_address_decode (CAMEL_ADDRESS (inet_addr), curl->path);
1948 		vfolder_gui_add_from_address (
1949 			session, inet_addr, AUTO_FROM, folder);
1950 		g_object_unref (inet_addr);
1951 	}
1952 
1953 	camel_url_free (curl);
1954 }
1955 
1956 static GtkActionEntry mail_reader_entries[] = {
1957 
1958 	{ "mail-add-sender",
1959 	  NULL,
1960 	  N_("A_dd Sender to Address Book"),
1961 	  NULL,
1962 	  N_("Add sender to address book"),
1963 	  G_CALLBACK (action_mail_add_sender_cb) },
1964 
1965 	{ "mail-check-for-junk",
1966 	  "mail-mark-junk",
1967 	  N_("Check for _Junk"),
1968 	  NULL,
1969 	  N_("Filter the selected messages for junk status"),
1970 	  G_CALLBACK (action_mail_check_for_junk_cb) },
1971 
1972 	{ "mail-copy",
1973 	  "mail-copy",
1974 	  N_("_Copy to Folder..."),
1975 	  "<Shift><Control>y",
1976 	  N_("Copy selected messages to another folder"),
1977 	  G_CALLBACK (action_mail_copy_cb) },
1978 
1979 	{ "mail-delete",
1980 	  "user-trash",
1981 	  N_("_Delete Message"),
1982 	  "<Control>d",
1983 	  N_("Mark the selected messages for deletion"),
1984 	  G_CALLBACK (action_mail_delete_cb) },
1985 
1986 	{ "mail-filter-rule-for-mailing-list",
1987 	  NULL,
1988 	  N_("Create a Filter Rule for Mailing _List..."),
1989 	  NULL,
1990 	  N_("Create a rule to filter messages to this mailing list"),
1991 	  G_CALLBACK (action_mail_filter_on_mailing_list_cb) },
1992 
1993 	{ "mail-filter-rule-for-recipients",
1994 	  NULL,
1995 	  N_("Create a Filter Rule for _Recipients..."),
1996 	  NULL,
1997 	  N_("Create a rule to filter messages to these recipients"),
1998 	  G_CALLBACK (action_mail_filter_on_recipients_cb) },
1999 
2000 	{ "mail-filter-rule-for-sender",
2001 	  NULL,
2002 	  N_("Create a Filter Rule for Se_nder..."),
2003 	  NULL,
2004 	  N_("Create a rule to filter messages from this sender"),
2005 	  G_CALLBACK (action_mail_filter_on_sender_cb) },
2006 
2007 	{ "mail-filter-rule-for-subject",
2008 	  NULL,
2009 	  N_("Create a Filter Rule for _Subject..."),
2010 	  NULL,
2011 	  N_("Create a rule to filter messages with this subject"),
2012 	  G_CALLBACK (action_mail_filter_on_subject_cb) },
2013 
2014 	{ "mail-filters-apply",
2015 	  "stock_mail-filters-apply",
2016 	  N_("A_pply Filters"),
2017 	  "<Control>y",
2018 	  N_("Apply filter rules to the selected messages"),
2019 	  G_CALLBACK (action_mail_filters_apply_cb) },
2020 
2021 	{ "mail-find",
2022 	  GTK_STOCK_FIND,
2023 	  N_("_Find in Message..."),
2024 	  "<Shift><Control>f",
2025 	  N_("Search for text in the body of the displayed message"),
2026 	  G_CALLBACK (action_mail_find_cb) },
2027 
2028 	{ "mail-flag-clear",
2029 	  NULL,
2030 	  N_("_Clear Flag"),
2031 	  NULL,
2032 	  N_("Remove the follow-up flag from the selected messages"),
2033 	  G_CALLBACK (action_mail_flag_clear_cb) },
2034 
2035 	{ "mail-flag-completed",
2036 	  NULL,
2037 	  N_("_Flag Completed"),
2038 	  NULL,
2039 	  N_("Set the follow-up flag to completed on the selected messages"),
2040 	  G_CALLBACK (action_mail_flag_completed_cb) },
2041 
2042 	{ "mail-flag-for-followup",
2043 	  "stock_mail-flag-for-followup",
2044 	  N_("Follow _Up..."),
2045 	  "<Shift><Control>g",
2046 	  N_("Flag the selected messages for follow-up"),
2047 	  G_CALLBACK (action_mail_flag_for_followup_cb) },
2048 
2049 	{ "mail-forward-attached",
2050 	  NULL,
2051 	  N_("_Attached"),
2052 	  NULL,
2053 	  N_("Forward the selected message to someone as an attachment"),
2054 	  G_CALLBACK (action_mail_forward_attached_cb) },
2055 
2056 	{ "mail-forward-attached-full",
2057 	  NULL,
2058 	  N_("Forward As _Attached"),
2059 	  NULL,
2060 	  N_("Forward the selected message to someone as an attachment"),
2061 	  G_CALLBACK (action_mail_forward_attached_cb) },
2062 
2063 	{ "mail-forward-inline",
2064 	  NULL,
2065 	  N_("_Inline"),
2066 	  NULL,
2067 	  N_("Forward the selected message in the body of a new message"),
2068 	  G_CALLBACK (action_mail_forward_inline_cb) },
2069 
2070 	{ "mail-forward-inline-full",
2071 	  NULL,
2072 	  N_("Forward As _Inline"),
2073 	  NULL,
2074 	  N_("Forward the selected message in the body of a new message"),
2075 	  G_CALLBACK (action_mail_forward_inline_cb) },
2076 
2077 	{ "mail-forward-quoted",
2078 	  NULL,
2079 	  N_("_Quoted"),
2080 	  NULL,
2081 	  N_("Forward the selected message quoted like a reply"),
2082 	  G_CALLBACK (action_mail_forward_quoted_cb) },
2083 
2084 	{ "mail-forward-quoted-full",
2085 	  NULL,
2086 	  N_("Forward As _Quoted"),
2087 	  NULL,
2088 	  N_("Forward the selected message quoted like a reply"),
2089 	  G_CALLBACK (action_mail_forward_quoted_cb) },
2090 
2091 	{ "mail-load-images",
2092 	  "image-x-generic",
2093 	  N_("_Load Images"),
2094 	  "<Control>i",
2095 	  N_("Force images in HTML mail to be loaded"),
2096 	  G_CALLBACK (action_mail_load_images_cb) },
2097 
2098 	{ "mail-mark-important",
2099 	  "mail-mark-important",
2100 	  N_("_Important"),
2101 	  NULL,
2102 	  N_("Mark the selected messages as important"),
2103 	  G_CALLBACK (action_mail_mark_important_cb) },
2104 
2105 	{ "mail-mark-junk",
2106 	  "mail-mark-junk",
2107 	  N_("_Junk"),
2108 	  "<Control>j",
2109 	  N_("Mark the selected messages as junk"),
2110 	  G_CALLBACK (action_mail_mark_junk_cb) },
2111 
2112 	{ "mail-mark-notjunk",
2113 	  "mail-mark-notjunk",
2114 	  N_("_Not Junk"),
2115 	  "<Shift><Control>j",
2116 	  N_("Mark the selected messages as not being junk"),
2117 	  G_CALLBACK (action_mail_mark_notjunk_cb) },
2118 
2119 	{ "mail-mark-read",
2120 	  "mail-mark-read",
2121 	  N_("_Read"),
2122 	  "<Control>k",
2123 	  N_("Mark the selected messages as having been read"),
2124 	  G_CALLBACK (action_mail_mark_read_cb) },
2125 
2126 	{ "mail-mark-unimportant",
2127 	  NULL,
2128 	  N_("Uni_mportant"),
2129 	  NULL,
2130 	  N_("Mark the selected messages as unimportant"),
2131 	  G_CALLBACK (action_mail_mark_unimportant_cb) },
2132 
2133 	{ "mail-mark-unread",
2134 	  "mail-mark-unread",
2135 	  N_("_Unread"),
2136 	  "<Shift><Control>k",
2137 	  N_("Mark the selected messages as not having been read"),
2138 	  G_CALLBACK (action_mail_mark_unread_cb) },
2139 
2140 	{ "mail-message-edit",
2141 	  NULL,
2142 	  N_("_Edit as New Message..."),
2143 	  NULL,
2144 	  N_("Open the selected messages in the composer for editing"),
2145 	  G_CALLBACK (action_mail_message_edit_cb) },
2146 
2147 	{ "mail-message-new",
2148 	  "mail-message-new",
2149 	  N_("Compose _New Message"),
2150 	  "<Shift><Control>m",
2151 	  N_("Open a window for composing a mail message"),
2152 	  G_CALLBACK (action_mail_message_new_cb) },
2153 
2154 	{ "mail-message-open",
2155 	  NULL,
2156 	  N_("_Open in New Window"),
2157 	  "<Control>o",
2158 	  N_("Open the selected messages in a new window"),
2159 	  G_CALLBACK (action_mail_message_open_cb) },
2160 
2161 	{ "mail-move",
2162 	  "mail-move",
2163 	  N_("_Move to Folder..."),
2164 	  "<Shift><Control>v",
2165 	  N_("Move selected messages to another folder"),
2166 	  G_CALLBACK (action_mail_move_cb) },
2167 
2168 	{ "mail-goto-folder",
2169 	  NULL,
2170 	  N_("_Switch to Folder"),
2171 	  "<Control>Up",
2172 	  N_("Display the parent folder"),
2173 	  G_CALLBACK (action_mail_folder_cb) },
2174 
2175 	{ "mail-goto-nexttab",
2176 	  NULL,
2177 	  N_("Switch to _next tab"),
2178 	  "<Shift><Control>Down",
2179 	  N_("Switch to the next tab"),
2180 	  G_CALLBACK (action_mail_nexttab_cb) },
2181 
2182 	{ "mail-goto-prevtab",
2183 	  NULL,
2184 	  N_("Switch to _previous tab"),
2185 	  "<Shift><Control>Up",
2186 	  N_("Switch to the previous tab"),
2187 	  G_CALLBACK (action_mail_prevtab_cb) },
2188 
2189 	{ "mail-close-tab",
2190 	  NULL,
2191 	  N_("Cl_ose current tab"),
2192 	  "<Shift><Control>w",
2193 	  N_("Close current tab"),
2194 	  G_CALLBACK (action_mail_closetab_cb) },
2195 
2196 	{ "mail-next",
2197 	  GTK_STOCK_GO_FORWARD,
2198 	  N_("_Next Message"),
2199 	  "<Control>Page_Down",
2200 	  N_("Display the next message"),
2201 	  G_CALLBACK (action_mail_next_cb) },
2202 
2203 	{ "mail-next-important",
2204 	  NULL,
2205 	  N_("Next _Important Message"),
2206 	  NULL,
2207 	  N_("Display the next important message"),
2208 	  G_CALLBACK (action_mail_next_important_cb) },
2209 
2210 	{ "mail-next-thread",
2211 	  NULL,
2212 	  N_("Next _Thread"),
2213 	  NULL,
2214 	  N_("Display the next thread"),
2215 	  G_CALLBACK (action_mail_next_thread_cb) },
2216 
2217 	{ "mail-next-unread",
2218 	  NULL,
2219 	  N_("Next _Unread Message"),
2220 	  "<Control>bracketright",
2221 	  N_("Display the next unread message"),
2222 	  G_CALLBACK (action_mail_next_unread_cb) },
2223 
2224 	{ "mail-previous",
2225 	  GTK_STOCK_GO_BACK,
2226 	  N_("_Previous Message"),
2227 	  "<Control>Page_Up",
2228 	  N_("Display the previous message"),
2229 	  G_CALLBACK (action_mail_previous_cb) },
2230 
2231 	{ "mail-previous-important",
2232 	  NULL,
2233 	  N_("Pr_evious Important Message"),
2234 	  NULL,
2235 	  N_("Display the previous important message"),
2236 	  G_CALLBACK (action_mail_previous_important_cb) },
2237 
2238 	{ "mail-previous-thread",
2239 	  NULL,
2240 	  N_("Previous T_hread"),
2241 	  NULL,
2242 	  N_("Display the previous thread"),
2243 	  G_CALLBACK (action_mail_previous_thread_cb) },
2244 
2245 	{ "mail-previous-unread",
2246 	  NULL,
2247 	  N_("P_revious Unread Message"),
2248 	  "<Control>bracketleft",
2249 	  N_("Display the previous unread message"),
2250 	  G_CALLBACK (action_mail_previous_unread_cb) },
2251 
2252 	{ "mail-print",
2253 	  GTK_STOCK_PRINT,
2254 	  NULL,
2255 	  "<Control>p",
2256 	  N_("Print this message"),
2257 	  G_CALLBACK (action_mail_print_cb) },
2258 
2259 	{ "mail-print-preview",
2260 	  GTK_STOCK_PRINT_PREVIEW,
2261 	  NULL,
2262 	  NULL,
2263 	  N_("Preview the message to be printed"),
2264 	  G_CALLBACK (action_mail_print_preview_cb) },
2265 
2266 	{ "mail-redirect",
2267 	  NULL,
2268 	  N_("Re_direct"),
2269 	  NULL,
2270 	  N_("Redirect (bounce) the selected message to someone"),
2271 	  G_CALLBACK (action_mail_redirect_cb) },
2272 
2273 	{ "mail-remove-attachments",
2274 	  GTK_STOCK_DELETE,
2275 	  N_("Remo_ve Attachments"),
2276 	  NULL,
2277 	  N_("Remove attachments"),
2278 	  G_CALLBACK (action_mail_remove_attachments_cb) },
2279 
2280 	{ "mail-remove-duplicates",
2281 	   NULL,
2282 	   N_("Remove Du_plicate Messages"),
2283 	   NULL,
2284 	   N_("Checks selected messages for duplicates"),
2285 	   G_CALLBACK (action_mail_remove_duplicates_cb) },
2286 
2287 	{ "mail-reply-all",
2288 	  NULL,
2289 	  N_("Reply to _All"),
2290 	  "<Shift><Control>r",
2291 	  N_("Compose a reply to all the recipients of the selected message"),
2292 	  G_CALLBACK (action_mail_reply_all_cb) },
2293 
2294 	{ "mail-reply-list",
2295 	  NULL,
2296 	  N_("Reply to _List"),
2297 	  "<Control>l",
2298 	  N_("Compose a reply to the mailing list of the selected message"),
2299 	  G_CALLBACK (action_mail_reply_list_cb) },
2300 
2301 	{ "mail-reply-sender",
2302 	  "mail-reply-sender",
2303 	  N_("_Reply to Sender"),
2304 	  "<Control>r",
2305 	  N_("Compose a reply to the sender of the selected message"),
2306 	  G_CALLBACK (action_mail_reply_sender_cb) },
2307 
2308 	{ "mail-save-as",
2309 	  GTK_STOCK_SAVE_AS,
2310 	  N_("_Save as mbox..."),
2311 	  "<Control>s",
2312 	  N_("Save selected messages as an mbox file"),
2313 	  G_CALLBACK (action_mail_save_as_cb) },
2314 
2315 	{ "mail-show-source",
2316 	  NULL,
2317 	  N_("_Message Source"),
2318 	  "<Control>u",
2319 	  N_("Show the raw email source of the message"),
2320 	  G_CALLBACK (action_mail_show_source_cb) },
2321 
2322 	{ "mail-toggle-important",
2323 	  NULL,
2324 	  NULL,  /* No menu item; key press only */
2325 	  NULL,
2326 	  NULL,
2327 	  G_CALLBACK (action_mail_toggle_important_cb) },
2328 
2329 	{ "mail-undelete",
2330 	  NULL,
2331 	  N_("_Undelete Message"),
2332 	  "<Shift><Control>d",
2333 	  N_("Undelete the selected messages"),
2334 	  G_CALLBACK (action_mail_undelete_cb) },
2335 
2336 	{ "mail-zoom-100",
2337 	  GTK_STOCK_ZOOM_100,
2338 	  N_("_Normal Size"),
2339 	  "<Control>0",
2340 	  N_("Reset the text to its original size"),
2341 	  G_CALLBACK (action_mail_zoom_100_cb) },
2342 
2343 	{ "mail-zoom-in",
2344 	  GTK_STOCK_ZOOM_IN,
2345 	  N_("_Zoom In"),
2346 	  "<Control>plus",
2347 	  N_("Increase the text size"),
2348 	  G_CALLBACK (action_mail_zoom_in_cb) },
2349 
2350 	{ "mail-zoom-out",
2351 	  GTK_STOCK_ZOOM_OUT,
2352 	  N_("Zoom _Out"),
2353 	  "<Control>minus",
2354 	  N_("Decrease the text size"),
2355 	  G_CALLBACK (action_mail_zoom_out_cb) },
2356 
2357 	/*** Menus ***/
2358 
2359 	{ "mail-create-menu",
2360 	  NULL,
2361 	  N_("Cre_ate"),
2362 	  NULL,
2363 	  NULL,
2364 	  NULL },
2365 
2366 	{ "mail-encoding-menu",
2367 	  NULL,
2368 	  N_("Ch_aracter Encoding"),
2369 	  NULL,
2370 	  NULL,
2371 	  NULL },
2372 
2373 	{ "mail-forward-as-menu",
2374 	  NULL,
2375 	  N_("F_orward As"),
2376 	  NULL,
2377 	  NULL,
2378 	  NULL },
2379 
2380 	{ "mail-reply-group-menu",
2381 	  NULL,
2382 	  N_("_Group Reply"),
2383 	  NULL,
2384 	  NULL,
2385 	  NULL },
2386 
2387 	{ "mail-goto-menu",
2388 	  GTK_STOCK_JUMP_TO,
2389 	  N_("_Go To"),
2390 	  NULL,
2391 	  NULL,
2392 	  NULL },
2393 
2394 	{ "mail-mark-as-menu",
2395 	  NULL,
2396 	  N_("Mar_k As"),
2397 	  NULL,
2398 	  NULL,
2399 	  NULL },
2400 
2401 	{ "mail-message-menu",
2402 	  NULL,
2403 	  N_("_Message"),
2404 	  NULL,
2405 	  NULL,
2406 	  NULL },
2407 
2408 	{ "mail-zoom-menu",
2409 	  NULL,
2410 	  N_("_Zoom"),
2411 	  NULL,
2412 	  NULL,
2413 	  NULL }
2414 };
2415 
2416 static GtkActionEntry mail_reader_search_folder_entries[] = {
2417 
2418 	{ "mail-search-folder-from-mailing-list",
2419 	  NULL,
2420 	  N_("Create a Search Folder from Mailing _List..."),
2421 	  NULL,
2422 	  N_("Create a search folder for this mailing list"),
2423 	  G_CALLBACK (action_mail_search_folder_from_mailing_list_cb) },
2424 
2425 	{ "mail-search-folder-from-recipients",
2426 	  NULL,
2427 	  N_("Create a Search Folder from Recipien_ts..."),
2428 	  NULL,
2429 	  N_("Create a search folder for these recipients"),
2430 	  G_CALLBACK (action_mail_search_folder_from_recipients_cb) },
2431 
2432 	{ "mail-search-folder-from-sender",
2433 	  NULL,
2434 	  N_("Create a Search Folder from Sen_der..."),
2435 	  NULL,
2436 	  N_("Create a search folder for this sender"),
2437 	  G_CALLBACK (action_mail_search_folder_from_sender_cb) },
2438 
2439 	{ "mail-search-folder-from-subject",
2440 	  NULL,
2441 	  N_("Create a Search Folder from S_ubject..."),
2442 	  NULL,
2443 	  N_("Create a search folder for this subject"),
2444 	  G_CALLBACK (action_mail_search_folder_from_subject_cb) },
2445 };
2446 
2447 static EPopupActionEntry mail_reader_popup_entries[] = {
2448 
2449 	{ "mail-popup-copy",
2450 	  NULL,
2451 	  "mail-copy" },
2452 
2453 	{ "mail-popup-delete",
2454 	  NULL,
2455 	  "mail-delete" },
2456 
2457 	{ "mail-popup-flag-clear",
2458 	  NULL,
2459 	  "mail-flag-clear" },
2460 
2461 	{ "mail-popup-flag-completed",
2462 	  NULL,
2463 	  "mail-flag-completed" },
2464 
2465 	{ "mail-popup-flag-for-followup",
2466 	  N_("Mark for Follo_w Up..."),
2467 	  "mail-flag-for-followup" },
2468 
2469 	{ "mail-popup-forward",
2470 	  NULL,
2471 	  "mail-forward" },
2472 
2473 	{ "mail-popup-mark-important",
2474 	  N_("Mark as _Important"),
2475 	  "mail-mark-important" },
2476 
2477 	{ "mail-popup-mark-junk",
2478 	  N_("Mark as _Junk"),
2479 	  "mail-mark-junk" },
2480 
2481 	{ "mail-popup-mark-notjunk",
2482 	  N_("Mark as _Not Junk"),
2483 	  "mail-mark-notjunk" },
2484 
2485 	{ "mail-popup-mark-read",
2486 	  N_("Mar_k as Read"),
2487 	  "mail-mark-read" },
2488 
2489 	{ "mail-popup-mark-unimportant",
2490 	  N_("Mark as Uni_mportant"),
2491 	  "mail-mark-unimportant" },
2492 
2493 	{ "mail-popup-mark-unread",
2494 	  N_("Mark as _Unread"),
2495 	  "mail-mark-unread" },
2496 
2497 	{ "mail-popup-message-edit",
2498 	  NULL,
2499 	  "mail-message-edit" },
2500 
2501 	{ "mail-popup-move",
2502 	  NULL,
2503 	  "mail-move" },
2504 
2505 	{ "mail-popup-print",
2506 	  NULL,
2507 	  "mail-print" },
2508 
2509 	{ "mail-popup-remove-attachments",
2510 	  NULL,
2511 	  "mail-remove-attachments" },
2512 
2513 	{ "mail-popup-remove-duplicates",
2514 	  NULL,
2515 	  "mail-remove-duplicates" },
2516 
2517 	{ "mail-popup-reply-all",
2518 	  NULL,
2519 	  "mail-reply-all" },
2520 
2521 	{ "mail-popup-reply-sender",
2522 	  NULL,
2523 	  "mail-reply-sender" },
2524 
2525 	{ "mail-popup-save-as",
2526 	  NULL,
2527 	  "mail-save-as" },
2528 
2529 	{ "mail-popup-undelete",
2530 	  NULL,
2531 	  "mail-undelete" }
2532 };
2533 
2534 static GtkToggleActionEntry mail_reader_toggle_entries[] = {
2535 
2536 	{ "mail-caret-mode",
2537 	  NULL,
2538 	  N_("_Caret Mode"),
2539 	  "F7",
2540 	  N_("Show a blinking cursor in the body of displayed messages"),
2541 	  NULL,  /* No callback required */
2542 	  FALSE },
2543 
2544 	{ "mail-show-all-headers",
2545 	  NULL,
2546 	  N_("All Message _Headers"),
2547 	  NULL,
2548 	  N_("Show messages with all email headers"),
2549 	  G_CALLBACK (action_mail_show_all_headers_cb),
2550 	  FALSE }
2551 };
2552 
2553 static void
2554 mail_reader_double_click_cb (EMailReader *reader,
2555                              gint row,
2556                              ETreePath path,
2557                              gint col,
2558                              GdkEvent *event)
2559 {
2560 	GtkAction *action;
2561 
2562 	/* Ignore double clicks on columns that handle their own state. */
2563 	if (MESSAGE_LIST_COLUMN_IS_ACTIVE (col))
2564 		return;
2565 
2566 	action = e_mail_reader_get_action (reader, "mail-message-open");
2567 	gtk_action_activate (action);
2568 }
2569 
2570 static gboolean
2571 mail_reader_key_press_event_cb (EMailReader *reader,
2572                                 GdkEventKey *event)
2573 {
2574 	GtkAction *action;
2575 	const gchar *action_name;
2576 
2577 	if ((event->state & GDK_CONTROL_MASK) != 0)
2578 		goto ctrl;
2579 
2580 	/* <keyval> alone */
2581 	switch (event->keyval) {
2582 		case GDK_KEY_Delete:
2583 		case GDK_KEY_KP_Delete:
2584 			action_name = "mail-delete";
2585 			break;
2586 
2587 		case GDK_KEY_Return:
2588 		case GDK_KEY_KP_Enter:
2589 		case GDK_KEY_ISO_Enter:
2590 			action_name = "mail-message-open";
2591 			break;
2592 
2593 		case GDK_KEY_period:
2594 		case GDK_KEY_bracketright:
2595 			action_name = "mail-next-unread";
2596 			break;
2597 
2598 		case GDK_KEY_comma:
2599 		case GDK_KEY_bracketleft:
2600 			action_name = "mail-previous-unread";
2601 			break;
2602 
2603 #ifdef HAVE_XFREE
2604 		case XF86XK_Reply:
2605 			action_name = "mail-reply-all";
2606 			break;
2607 
2608 		case XF86XK_MailForward:
2609 			action_name = "mail-forward";
2610 			break;
2611 #endif
2612 
2613 		case GDK_KEY_exclam:
2614 			action_name = "mail-toggle-important";
2615 			break;
2616 
2617 		default:
2618 			return FALSE;
2619 	}
2620 
2621 	goto exit;
2622 
2623 ctrl:
2624 
2625 	/* Ctrl + <keyval> */
2626 	switch (event->keyval) {
2627 		case GDK_KEY_period:
2628 			action_name = "mail-next-unread";
2629 			break;
2630 
2631 		case GDK_KEY_comma:
2632 			action_name = "mail-previous-unread";
2633 			break;
2634 
2635 		default:
2636 			return FALSE;
2637 	}
2638 
2639 exit:
2640 	action = e_mail_reader_get_action (reader, action_name);
2641 	gtk_action_activate (action);
2642 
2643 	return TRUE;
2644 }
2645 
2646 static gint
2647 mail_reader_key_press_cb (EMailReader *reader,
2648                           gint row,
2649                           ETreePath path,
2650                           gint col,
2651                           GdkEvent *event)
2652 {
2653 	return mail_reader_key_press_event_cb (reader, &event->key);
2654 }
2655 
2656 static gboolean
2657 mail_reader_message_seen_cb (EMailReaderClosure *closure)
2658 {
2659 	EMailReader *reader;
2660 	GtkWidget *message_list;
2661 	EMailPartList *parts;
2662 	EMailDisplay *display;
2663 	CamelMimeMessage *message;
2664 	const gchar *current_uid;
2665 	const gchar *message_uid;
2666 	gboolean uid_is_current = TRUE;
2667 
2668 	reader = closure->reader;
2669 	message_uid = closure->message_uid;
2670 
2671 	display = e_mail_reader_get_mail_display (reader);
2672 	parts = e_mail_display_get_parts_list (display);
2673 	message_list = e_mail_reader_get_message_list (reader);
2674 
2675 	if (e_tree_is_dragging (E_TREE (message_list)))
2676 		return FALSE;
2677 
2678 	current_uid = MESSAGE_LIST (message_list)->cursor_uid;
2679 	uid_is_current &= (g_strcmp0 (current_uid, message_uid) == 0);
2680 
2681 	if (parts)
2682 		message = parts->message;
2683 	else
2684 		message = NULL;
2685 
2686 	if (uid_is_current && message != NULL)
2687 		g_signal_emit (
2688 			reader, signals[MESSAGE_SEEN], 0,
2689 			message_uid, message);
2690 
2691 	return FALSE;
2692 }
2693 
2694 static gboolean
2695 schedule_timeout_mark_seen (EMailReader *reader)
2696 {
2697 	EShell *shell;
2698 	EMailBackend *backend;
2699 	EShellBackend *shell_backend;
2700 	EShellSettings *shell_settings;
2701 	MessageList *message_list;
2702 	gboolean schedule_timeout;
2703 	gint timeout_interval;
2704 	const gchar *message_uid;
2705 	backend = e_mail_reader_get_backend (reader);
2706 	message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
2707 	shell_backend = E_SHELL_BACKEND (backend);
2708 	shell = e_shell_backend_get_shell (shell_backend);
2709 	shell_settings = e_shell_get_shell_settings (shell);
2710 
2711 	message_uid = message_list->cursor_uid;
2712 	if (message_uid == NULL ||
2713 	    e_tree_is_dragging (E_TREE (message_list)))
2714 		return FALSE;
2715 
2716 	schedule_timeout =
2717 		(message_uid != NULL) &&
2718 		e_shell_settings_get_boolean (
2719 			shell_settings, "mail-mark-seen");
2720 	timeout_interval =
2721 		e_shell_settings_get_int (
2722 		shell_settings, "mail-mark-seen-timeout");
2723 
2724 	if (message_list->seen_id > 0) {
2725 		g_source_remove (message_list->seen_id);
2726 		message_list->seen_id = 0;
2727 	}
2728 
2729 	if (schedule_timeout) {
2730 		EMailReaderClosure *timeout_closure;
2731 
2732 		timeout_closure = g_slice_new0 (EMailReaderClosure);
2733 		timeout_closure->reader = g_object_ref (reader);
2734 		timeout_closure->message_uid = g_strdup (message_uid);
2735 
2736 		MESSAGE_LIST (message_list)->seen_id = g_timeout_add_full (
2737 			G_PRIORITY_DEFAULT, timeout_interval,
2738 			(GSourceFunc) mail_reader_message_seen_cb,
2739 			timeout_closure, (GDestroyNotify)
2740 			mail_reader_closure_free);
2741 	}
2742 
2743 	return schedule_timeout;
2744 }
2745 
2746 static gboolean
2747 discard_timeout_mark_seen_cb (EMailReader *reader)
2748 {
2749 	MessageList *message_list;
2750 
2751 	g_return_val_if_fail (reader != NULL, FALSE);
2752 
2753 	message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
2754 	g_return_val_if_fail (message_list != NULL, FALSE);
2755 
2756 	if (message_list->seen_id > 0) {
2757 		g_source_remove (message_list->seen_id);
2758 		message_list->seen_id = 0;
2759 	}
2760 
2761 	return FALSE;
2762 }
2763 
2764 static void
2765 mail_reader_message_loaded_cb (CamelFolder *folder,
2766                                GAsyncResult *result,
2767                                EMailReaderClosure *closure)
2768 {
2769 	EMailReader *reader;
2770 	EMailReaderPrivate *priv;
2771 	CamelMimeMessage *message = NULL;
2772 	GtkWidget *message_list;
2773 	const gchar *message_uid;
2774 	GError *error = NULL;
2775 
2776 	reader = closure->reader;
2777 	message_uid = closure->message_uid;
2778 
2779 	priv = E_MAIL_READER_GET_PRIVATE (reader);
2780 
2781 	/* If the private struct is NULL, the EMailReader was destroyed
2782 	 * while we were loading the message and we're likely holding the
2783 	 * last reference.  Nothing to do but drop the reference. */
2784 	if (priv == NULL) {
2785 		mail_reader_closure_free (closure);
2786 		return;
2787 	}
2788 
2789 	message = camel_folder_get_message_finish (folder, result, &error);
2790 
2791 	/* If the user picked a different message in the time it took
2792 	 * to fetch this message, then don't bother rendering it. */
2793 	if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
2794 		g_clear_error (&error);
2795 		goto exit;
2796 	}
2797 
2798 	message_list = e_mail_reader_get_message_list (reader);
2799 
2800 	if (!message_list) {
2801 		/* for cases where message fetching took so long that
2802 		 * user closed the message window before this was called */
2803 		goto exit;
2804 	}
2805 
2806 	if (message != NULL)
2807 		g_signal_emit (
2808 			reader, signals[MESSAGE_LOADED], 0,
2809 			message_uid, message);
2810 
2811 exit:
2812 	priv->restoring_message_selection = FALSE;
2813 	if (error) {
2814 		EPreviewPane *preview_pane;
2815 		EWebView *web_view;
2816 
2817 		preview_pane = e_mail_reader_get_preview_pane (reader);
2818 		web_view = e_preview_pane_get_web_view (preview_pane);
2819 
2820 		e_alert_submit (
2821 			E_ALERT_SINK (web_view),
2822 			"mail:no-retrieve-message",
2823 			error->message, NULL);
2824 	}
2825 
2826 	g_clear_error (&error);
2827 
2828 	mail_reader_closure_free (closure);
2829 
2830 	if (message)
2831 		g_object_unref (message);
2832 }
2833 
2834 static gboolean
2835 mail_reader_message_selected_timeout_cb (EMailReader *reader)
2836 {
2837 	EMailReaderPrivate *priv;
2838 	EMailDisplay *display;
2839 	GtkWidget *message_list;
2840 	CamelFolder *folder;
2841 	const gchar *cursor_uid;
2842 	const gchar *format_uid;
2843 	EMailPartList *parts;
2844 
2845 	priv = E_MAIL_READER_GET_PRIVATE (reader);
2846 
2847 	folder = e_mail_reader_get_folder (reader);
2848 
2849 	message_list = e_mail_reader_get_message_list (reader);
2850 	display = e_mail_reader_get_mail_display (reader);
2851 	parts = e_mail_display_get_parts_list (display);
2852 
2853 	cursor_uid = MESSAGE_LIST (message_list)->cursor_uid;
2854 	format_uid = parts ? parts->message_uid : NULL;
2855 
2856 	if (MESSAGE_LIST (message_list)->last_sel_single) {
2857 		GtkWidget *widget;
2858 		gboolean display_visible;
2859 		gboolean selected_uid_changed;
2860 
2861 		/* Decide whether to download the full message now. */
2862 		widget = GTK_WIDGET (display);
2863 		display_visible = gtk_widget_get_mapped (widget);
2864 
2865 		selected_uid_changed = (g_strcmp0 (cursor_uid, format_uid) != 0);
2866 
2867 		if (display_visible && selected_uid_changed) {
2868 			EMailReaderClosure *closure;
2869 			GCancellable *cancellable;
2870 			EActivity *activity;
2871 			gchar *string;
2872 
2873 			string = g_strdup_printf (_("Retrieving message '%s'"), cursor_uid);
2874 			e_mail_display_set_parts_list (display, NULL);
2875 			e_mail_display_set_status (display, string);
2876 			g_free (string);
2877 
2878 			activity = e_mail_reader_new_activity (reader);
2879 			e_activity_set_text (activity, _("Retrieving message"));
2880 			cancellable = e_activity_get_cancellable (activity);
2881 
2882 			closure = g_slice_new0 (EMailReaderClosure);
2883 			closure->activity = activity;
2884 			closure->reader = g_object_ref (reader);
2885 			closure->message_uid = g_strdup (cursor_uid);
2886 
2887 			camel_folder_get_message (
2888 				folder, cursor_uid, G_PRIORITY_DEFAULT,
2889 				cancellable, (GAsyncReadyCallback)
2890 				mail_reader_message_loaded_cb, closure);
2891 
2892 			if (priv->retrieving_message != NULL)
2893 				g_object_unref (priv->retrieving_message);
2894 			priv->retrieving_message = g_object_ref (cancellable);
2895 		}
2896 	} else {
2897 		e_mail_display_set_parts_list (display, NULL);
2898 		priv->restoring_message_selection = FALSE;
2899 	}
2900 
2901 	priv->message_selected_timeout_id = 0;
2902 
2903 	return FALSE;
2904 }
2905 
2906 static void
2907 mail_reader_message_selected_cb (EMailReader *reader,
2908                                  const gchar *message_uid)
2909 {
2910 	EMailReaderPrivate *priv;
2911 	MessageList *message_list;
2912 
2913 	priv = E_MAIL_READER_GET_PRIVATE (reader);
2914 
2915 	/* Cancel the previous message retrieval activity. */
2916 	g_cancellable_cancel (priv->retrieving_message);
2917 
2918 	/* Cancel the seen timer. */
2919 	message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
2920 	if (message_list && message_list->seen_id) {
2921 		g_source_remove (message_list->seen_id);
2922 		message_list->seen_id = 0;
2923 	}
2924 
2925 	/* Cancel the message selected timer. */
2926 	if (priv->message_selected_timeout_id > 0) {
2927 		g_source_remove (priv->message_selected_timeout_id);
2928 		priv->message_selected_timeout_id = 0;
2929 	}
2930 
2931 	/* If a folder was just selected then we are now automatically
2932 	 * restoring the previous message selection.  We behave slightly
2933 	 * differently than if the user had selected the message. */
2934 	priv->restoring_message_selection = priv->folder_was_just_selected;
2935 	priv->folder_was_just_selected = FALSE;
2936 
2937 	if (message_list_selected_count (message_list) != 1) {
2938 		EMailDisplay *display = e_mail_reader_get_mail_display (reader);
2939 
2940 		e_mail_display_set_parts_list (display, NULL);
2941 		e_web_view_clear (E_WEB_VIEW (display));
2942 	} else if (priv->restoring_message_selection) {
2943 		/* Skip the timeout if we're restoring the previous message
2944 		 * selection.  The timeout is there for when we're scrolling
2945 		 * rapidly through the message list. */
2946 		mail_reader_message_selected_timeout_cb (reader);
2947 	} else {
2948 		priv->message_selected_timeout_id = g_timeout_add (
2949 			100, (GSourceFunc)
2950 			mail_reader_message_selected_timeout_cb, reader);
2951 	}
2952 
2953 	e_mail_reader_changed (reader);
2954 }
2955 
2956 static void
2957 mail_reader_message_cursor_change_cb (EMailReader *reader)
2958 {
2959 	MessageList *message_list;
2960 	EMailReaderPrivate *priv;
2961 
2962 	g_return_if_fail (reader != NULL);
2963 
2964 	priv = E_MAIL_READER_GET_PRIVATE (reader);
2965 	g_return_if_fail (priv != NULL);
2966 
2967 	message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
2968 	g_return_if_fail (message_list != NULL);
2969 
2970 	if (message_list->seen_id == 0 &&
2971 	    E_IS_MAIL_VIEW (reader) &&
2972 	    e_mail_view_get_preview_visible (E_MAIL_VIEW (reader)) &&
2973 	    !priv->avoid_next_mark_as_seen)
2974 		schedule_timeout_mark_seen (reader);
2975 }
2976 
2977 static void
2978 mail_reader_emit_folder_loaded (EMailReader *reader)
2979 {
2980 	EMailReaderPrivate *priv;
2981 	MessageList *message_list;
2982 
2983 	priv = E_MAIL_READER_GET_PRIVATE (reader);
2984 	message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
2985 
2986 	if (priv && (message_list_count (message_list) <= 0 ||
2987 	    message_list_selected_count (message_list) <= 0))
2988 		priv->avoid_next_mark_as_seen = FALSE;
2989 
2990 	g_signal_emit (reader, signals[FOLDER_LOADED], 0);
2991 }
2992 
2993 static EAlertSink *
2994 mail_reader_get_alert_sink (EMailReader *reader)
2995 {
2996 	EPreviewPane *preview_pane;
2997 
2998 	preview_pane = e_mail_reader_get_preview_pane (reader);
2999 
3000 	return E_ALERT_SINK (preview_pane);
3001 }
3002 
3003 static GPtrArray *
3004 mail_reader_get_selected_uids (EMailReader *reader)
3005 {
3006 	GtkWidget *message_list;
3007 
3008 	message_list = e_mail_reader_get_message_list (reader);
3009 
3010 	return message_list_get_selected (MESSAGE_LIST (message_list));
3011 }
3012 
3013 static CamelFolder *
3014 mail_reader_get_folder (EMailReader *reader)
3015 {
3016 	GtkWidget *message_list;
3017 
3018 	message_list = e_mail_reader_get_message_list (reader);
3019 
3020 	return MESSAGE_LIST (message_list)->folder;
3021 }
3022 
3023 static gboolean
3024 mail_reader_get_enable_show_folder (EMailReader *reader)
3025 {
3026 	return FALSE;
3027 }
3028 
3029 static void
3030 mail_reader_set_folder (EMailReader *reader,
3031                         CamelFolder *folder)
3032 {
3033 	EMailReaderPrivate *priv;
3034 	EMailDisplay *display;
3035 	CamelFolder *previous_folder;
3036 	ESourceRegistry *registry;
3037 	GtkWidget *message_list;
3038 	EMailBackend *backend;
3039 	EShell *shell;
3040 	gboolean outgoing;
3041 	gboolean sync_folder;
3042 
3043 	priv = E_MAIL_READER_GET_PRIVATE (reader);
3044 
3045 	backend = e_mail_reader_get_backend (reader);
3046 	display = e_mail_reader_get_mail_display (reader);
3047 	message_list = e_mail_reader_get_message_list (reader);
3048 
3049 	previous_folder = e_mail_reader_get_folder (reader);
3050 
3051 	backend = e_mail_reader_get_backend (reader);
3052 	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
3053 	registry = e_shell_get_registry (shell);
3054 
3055 	/* Only synchronize the real folder if we're online. */
3056 	sync_folder =
3057 		(previous_folder != NULL) &&
3058 		(CAMEL_IS_VEE_FOLDER (previous_folder) ||
3059 		e_shell_get_online (shell));
3060 	if (sync_folder)
3061 		mail_sync_folder (previous_folder, NULL, NULL);
3062 
3063 	/* Skip the rest if we're already viewing the folder. */
3064 	if (folder == previous_folder)
3065 		return;
3066 
3067 	outgoing = folder != NULL && (
3068 		em_utils_folder_is_drafts (registry, folder) ||
3069 		em_utils_folder_is_outbox (registry, folder) ||
3070 		em_utils_folder_is_sent (registry, folder));
3071 
3072 	e_web_view_clear (E_WEB_VIEW (display));
3073 
3074 	priv->folder_was_just_selected = (folder != NULL);
3075 
3076 	/* this is to make sure any post-poned changes in Search Folders
3077 	 * will be propagated on folder selection */
3078 	if (folder && CAMEL_IS_VEE_FOLDER (folder))
3079 		mail_sync_folder (folder, NULL, NULL);
3080 
3081 	message_list_set_folder (
3082 		MESSAGE_LIST (message_list), folder, outgoing);
3083 
3084 	mail_reader_emit_folder_loaded (reader);
3085 }
3086 
3087 static void
3088 mail_reader_set_message (EMailReader *reader,
3089                          const gchar *message_uid)
3090 {
3091 	GtkWidget *message_list;
3092 
3093 	message_list = e_mail_reader_get_message_list (reader);
3094 
3095 	message_list_select_uid (
3096 		MESSAGE_LIST (message_list), message_uid, FALSE);
3097 }
3098 
3099 static void
3100 mail_reader_folder_loaded (EMailReader *reader)
3101 {
3102 	guint32 state;
3103 
3104 	state = e_mail_reader_check_state (reader);
3105 	e_mail_reader_update_actions (reader, state);
3106 }
3107 
3108 struct format_parser_async_closure_ {
3109 	struct _formatter_weak_ref_closure *weak_ref_closure;
3110         EMailDisplay *display;
3111         EActivity *activity;
3112 };
3113 
3114 static void
3115 set_mail_display_part_list (GObject *object,
3116                             GAsyncResult *result,
3117                             gpointer user_data)
3118 {
3119 	EMailPartList *part_list;
3120 	EMailReader *reader;
3121 	EMailDisplay *display;
3122 
3123 	reader = E_MAIL_READER (object);
3124 	display = e_mail_reader_get_mail_display (reader);
3125 
3126 	part_list = e_mail_reader_parse_message_finish (reader, result);
3127 
3128 	e_mail_display_set_parts_list (display, part_list);
3129 	e_mail_display_load (display, NULL);
3130 
3131         /* Remove the reference added when parts list was created,
3132          * so that only owners are EMailDisplays */
3133 	g_object_unref (part_list);
3134 }
3135 
3136 static void
3137 mail_reader_set_display_formatter_for_message (EMailReader *reader,
3138                                                EMailDisplay *display,
3139                                                const gchar *message_uid,
3140                                                CamelMimeMessage *message,
3141                                                CamelFolder *folder)
3142 {
3143 	CamelObjectBag *registry;
3144 	EMailPartList *parts;
3145 	EMailReaderPrivate *priv;
3146 	gchar *mail_uri;
3147 
3148 	priv = E_MAIL_READER_GET_PRIVATE (reader);
3149 	mail_uri = e_mail_part_build_uri (folder, message_uid, NULL, NULL);
3150 	registry = e_mail_part_list_get_registry ();
3151 	parts = camel_object_bag_peek (registry, mail_uri);
3152 	g_free (mail_uri);
3153 
3154 	if (parts == NULL) {
3155 
3156 		e_mail_reader_parse_message (
3157 			reader, folder, message_uid, message,
3158 			priv->retrieving_message,
3159 			set_mail_display_part_list, NULL);
3160 
3161 	} else {
3162 		e_mail_display_set_parts_list (display, parts);
3163 		e_mail_display_load (display, NULL);
3164 		g_object_unref (parts);
3165 	}
3166 }
3167 
3168 static void
3169 mail_reader_message_loaded (EMailReader *reader,
3170                             const gchar *message_uid,
3171                             CamelMimeMessage *message)
3172 {
3173 	EMailReaderPrivate *priv;
3174 	GtkWidget *message_list;
3175 	EMailBackend *backend;
3176 	CamelFolder *folder;
3177 	EMailDisplay *display;
3178 	EShellBackend *shell_backend;
3179 	EShell *shell;
3180 	EMEvent *event;
3181 	EMEventTargetMessage *target;
3182 	GError *error = NULL;
3183 
3184 	priv = E_MAIL_READER_GET_PRIVATE (reader);
3185 
3186 	folder = e_mail_reader_get_folder (reader);
3187 	backend = e_mail_reader_get_backend (reader);
3188 	display = e_mail_reader_get_mail_display (reader);
3189 	message_list = e_mail_reader_get_message_list (reader);
3190 
3191 	shell_backend = E_SHELL_BACKEND (backend);
3192 	shell = e_shell_backend_get_shell (shell_backend);
3193 
3194 	/** @Event: message.reading
3195 	 * @Title: Viewing a message
3196 	 * @Target: EMEventTargetMessage
3197 	 *
3198 	 * message.reading is emitted whenever a user views a message.
3199 	 */
3200 	event = em_event_peek ();
3201 	target = em_event_target_new_message (
3202 		event, folder, message, message_uid, 0, NULL);
3203 	e_event_emit (
3204 		(EEvent *) event, "message.reading",
3205 		(EEventTarget *) target);
3206 
3207 	mail_reader_set_display_formatter_for_message (
3208 		reader, display, message_uid, message, folder);
3209 
3210 	/* Reset the shell view icon. */
3211 	e_shell_event (shell, "mail-icon", (gpointer) "evolution-mail");
3212 
3213 	if (MESSAGE_LIST (message_list)->seen_id > 0) {
3214 		g_source_remove (MESSAGE_LIST (message_list)->seen_id);
3215 		MESSAGE_LIST (message_list)->seen_id = 0;
3216 	}
3217 
3218 	/* Determine whether to mark the message as read. */
3219 	if (message != NULL &&
3220 	    !priv->restoring_message_selection &&
3221 	    !priv->avoid_next_mark_as_seen &&
3222 	    schedule_timeout_mark_seen (reader)) {
3223 		g_clear_error (&error);
3224 	} else if (error != NULL) {
3225 		e_alert_submit (
3226 			E_ALERT_SINK (display),
3227 			"mail:no-retrieve-message",
3228 			error->message, NULL);
3229 		g_error_free (error);
3230 	}
3231 
3232 	priv->avoid_next_mark_as_seen = FALSE;
3233 }
3234 
3235 static void
3236 mail_reader_message_seen (EMailReader *reader,
3237                           const gchar *message_uid,
3238                           CamelMimeMessage *message)
3239 {
3240 	CamelFolder *folder;
3241 	guint32 mask, set;
3242 
3243 	mask = CAMEL_MESSAGE_SEEN;
3244 	set  = CAMEL_MESSAGE_SEEN;
3245 
3246 	folder = e_mail_reader_get_folder (reader);
3247 	camel_folder_set_message_flags (folder, message_uid, mask, set);
3248 }
3249 
3250 static void
3251 mail_reader_show_search_bar (EMailReader *reader)
3252 {
3253 	EPreviewPane *preview_pane;
3254 
3255 	preview_pane = e_mail_reader_get_preview_pane (reader);
3256 	e_preview_pane_show_search_bar (preview_pane);
3257 }
3258 
3259 static void
3260 mail_reader_update_actions (EMailReader *reader,
3261                             guint32 state)
3262 {
3263 	GtkAction *action;
3264 	const gchar *action_name;
3265 	gboolean sensitive;
3266 
3267 	/* Be descriptive. */
3268 	gboolean any_messages_selected;
3269 	gboolean enable_flag_clear;
3270 	gboolean enable_flag_completed;
3271 	gboolean enable_flag_for_followup;
3272 	gboolean have_enabled_account;
3273 	gboolean multiple_messages_selected;
3274 	gboolean selection_has_attachment_messages;
3275 	gboolean selection_has_deleted_messages;
3276 	gboolean selection_has_important_messages;
3277 	gboolean selection_has_junk_messages;
3278 	gboolean selection_has_not_junk_messages;
3279 	gboolean selection_has_read_messages;
3280 	gboolean selection_has_undeleted_messages;
3281 	gboolean selection_has_unimportant_messages;
3282 	gboolean selection_has_unread_messages;
3283 	gboolean selection_is_mailing_list;
3284 	gboolean single_message_selected;
3285 	gboolean first_message_selected = FALSE;
3286 	gboolean last_message_selected = FALSE;
3287 
3288 	have_enabled_account =
3289 		(state & E_MAIL_READER_HAVE_ENABLED_ACCOUNT);
3290 	single_message_selected =
3291 		(state & E_MAIL_READER_SELECTION_SINGLE);
3292 	multiple_messages_selected =
3293 		(state & E_MAIL_READER_SELECTION_MULTIPLE);
3294 	/* FIXME Missing CAN_ADD_SENDER */
3295 	enable_flag_clear =
3296 		(state & E_MAIL_READER_SELECTION_FLAG_CLEAR);
3297 	enable_flag_completed =
3298 		(state & E_MAIL_READER_SELECTION_FLAG_COMPLETED);
3299 	enable_flag_for_followup =
3300 		(state & E_MAIL_READER_SELECTION_FLAG_FOLLOWUP);
3301 	selection_has_attachment_messages =
3302 		(state & E_MAIL_READER_SELECTION_HAS_ATTACHMENTS);
3303 	selection_has_deleted_messages =
3304 		(state & E_MAIL_READER_SELECTION_HAS_DELETED);
3305 	selection_has_important_messages =
3306 		(state & E_MAIL_READER_SELECTION_HAS_IMPORTANT);
3307 	selection_has_junk_messages =
3308 		(state & E_MAIL_READER_SELECTION_HAS_JUNK);
3309 	selection_has_not_junk_messages =
3310 		(state & E_MAIL_READER_SELECTION_HAS_NOT_JUNK);
3311 	selection_has_read_messages =
3312 		(state & E_MAIL_READER_SELECTION_HAS_READ);
3313 	selection_has_undeleted_messages =
3314 		(state & E_MAIL_READER_SELECTION_HAS_UNDELETED);
3315 	selection_has_unimportant_messages =
3316 		(state & E_MAIL_READER_SELECTION_HAS_UNIMPORTANT);
3317 	selection_has_unread_messages =
3318 		(state & E_MAIL_READER_SELECTION_HAS_UNREAD);
3319 	selection_is_mailing_list =
3320 		(state & E_MAIL_READER_SELECTION_IS_MAILING_LIST);
3321 
3322 	any_messages_selected =
3323 		(single_message_selected || multiple_messages_selected);
3324 
3325 	if (any_messages_selected) {
3326 		MessageList *message_list;
3327 		gint row = -1, count = -1;
3328 		ETreeTableAdapter *etta;
3329 		ETreePath node = NULL;
3330 
3331 		message_list = MESSAGE_LIST (
3332 			e_mail_reader_get_message_list (reader));
3333 		etta = e_tree_get_table_adapter (E_TREE (message_list));
3334 
3335 		if (message_list->cursor_uid != NULL)
3336 			node = g_hash_table_lookup (
3337 				message_list->uid_nodemap,
3338 				message_list->cursor_uid);
3339 
3340 		if (node != NULL) {
3341 			row = e_tree_table_adapter_row_of_node (etta, node);
3342 			count = e_table_model_row_count (E_TABLE_MODEL (etta));
3343 		}
3344 
3345 		first_message_selected = row <= 0;
3346 		last_message_selected = row < 0 || row + 1 >= count;
3347 	}
3348 
3349 	action_name = "mail-add-sender";
3350 	sensitive = single_message_selected;
3351 	action = e_mail_reader_get_action (reader, action_name);
3352 	gtk_action_set_sensitive (action, sensitive);
3353 
3354 	action_name = "mail-check-for-junk";
3355 	sensitive = any_messages_selected;
3356 	action = e_mail_reader_get_action (reader, action_name);
3357 	gtk_action_set_sensitive (action, sensitive);
3358 
3359 	action_name = "mail-copy";
3360 	sensitive = any_messages_selected;
3361 	action = e_mail_reader_get_action (reader, action_name);
3362 	gtk_action_set_sensitive (action, sensitive);
3363 
3364 	action_name = "mail-create-menu";
3365 	sensitive = single_message_selected;
3366 	action = e_mail_reader_get_action (reader, action_name);
3367 	gtk_action_set_sensitive (action, sensitive);
3368 
3369 	/* If a single message is selected, let the user hit delete to
3370 	 * advance the cursor even if the message is already deleted. */
3371 	action_name = "mail-delete";
3372 	sensitive =
3373 		single_message_selected ||
3374 		selection_has_undeleted_messages;
3375 	action = e_mail_reader_get_action (reader, action_name);
3376 	gtk_action_set_sensitive (action, sensitive);
3377 
3378 	action_name = "mail-filters-apply";
3379 	sensitive = any_messages_selected;
3380 	action = e_mail_reader_get_action (reader, action_name);
3381 	gtk_action_set_sensitive (action, sensitive);
3382 
3383 	action_name = "mail-find";
3384 	sensitive = single_message_selected;
3385 	action = e_mail_reader_get_action (reader, action_name);
3386 	gtk_action_set_sensitive (action, sensitive);
3387 
3388 	action_name = "mail-flag-clear";
3389 	sensitive = enable_flag_clear;
3390 	action = e_mail_reader_get_action (reader, action_name);
3391 	gtk_action_set_sensitive (action, sensitive);
3392 
3393 	action_name = "mail-flag-completed";
3394 	sensitive = enable_flag_completed;
3395 	action = e_mail_reader_get_action (reader, action_name);
3396 	gtk_action_set_sensitive (action, sensitive);
3397 
3398 	action_name = "mail-flag-for-followup";
3399 	sensitive = enable_flag_for_followup;
3400 	action = e_mail_reader_get_action (reader, action_name);
3401 	gtk_action_set_sensitive (action, sensitive);
3402 
3403 	action_name = "mail-forward";
3404 	sensitive = have_enabled_account && any_messages_selected;
3405 	action = e_mail_reader_get_action (reader, action_name);
3406 	gtk_action_set_sensitive (action, sensitive);
3407 
3408 	action_name = "mail-forward-attached";
3409 	sensitive = have_enabled_account && any_messages_selected;
3410 	action = e_mail_reader_get_action (reader, action_name);
3411 	gtk_action_set_sensitive (action, sensitive);
3412 
3413 	action_name = "mail-forward-attached-full";
3414 	sensitive = have_enabled_account && any_messages_selected;
3415 	action = e_mail_reader_get_action (reader, action_name);
3416 	gtk_action_set_sensitive (action, sensitive);
3417 
3418 	action_name = "mail-forward-as-menu";
3419 	sensitive = have_enabled_account && any_messages_selected;
3420 	action = e_mail_reader_get_action (reader, action_name);
3421 	gtk_action_set_sensitive (action, sensitive);
3422 
3423 	action_name = "mail-forward-inline";
3424 	sensitive = have_enabled_account && single_message_selected;
3425 	action = e_mail_reader_get_action (reader, action_name);
3426 	gtk_action_set_sensitive (action, sensitive);
3427 
3428 	action_name = "mail-forward-inline-full";
3429 	sensitive = have_enabled_account && single_message_selected;
3430 	action = e_mail_reader_get_action (reader, action_name);
3431 	gtk_action_set_sensitive (action, sensitive);
3432 
3433 	action_name = "mail-forward-quoted";
3434 	sensitive = have_enabled_account && single_message_selected;
3435 	action = e_mail_reader_get_action (reader, action_name);
3436 	gtk_action_set_sensitive (action, sensitive);
3437 
3438 	action_name = "mail-forward-quoted-full";
3439 	sensitive = have_enabled_account && single_message_selected;
3440 	action = e_mail_reader_get_action (reader, action_name);
3441 	gtk_action_set_sensitive (action, sensitive);
3442 
3443 	action_name = "mail-goto-menu";
3444 	sensitive = any_messages_selected;
3445 	action = e_mail_reader_get_action (reader, action_name);
3446 	gtk_action_set_sensitive (action, sensitive);
3447 
3448 	action_name = "mail-load-images";
3449 	sensitive = single_message_selected;
3450 	action = e_mail_reader_get_action (reader, action_name);
3451 	gtk_action_set_sensitive (action, sensitive);
3452 
3453 	action_name = "mail-mark-as-menu";
3454 	sensitive = any_messages_selected;
3455 	action = e_mail_reader_get_action (reader, action_name);
3456 	gtk_action_set_sensitive (action, sensitive);
3457 
3458 	action_name = "mail-mark-important";
3459 	sensitive = selection_has_unimportant_messages;
3460 	action = e_mail_reader_get_action (reader, action_name);
3461 	gtk_action_set_sensitive (action, sensitive);
3462 
3463 	action_name = "mail-mark-junk";
3464 	sensitive =
3465 		selection_has_not_junk_messages &&
3466 		!(state & E_MAIL_READER_FOLDER_IS_JUNK);
3467 	action = e_mail_reader_get_action (reader, action_name);
3468 	gtk_action_set_sensitive (action, sensitive);
3469 
3470 	action_name = "mail-mark-notjunk";
3471 	sensitive = selection_has_junk_messages;
3472 	action = e_mail_reader_get_action (reader, action_name);
3473 	gtk_action_set_sensitive (action, sensitive);
3474 
3475 	action_name = "mail-mark-read";
3476 	sensitive = selection_has_unread_messages;
3477 	action = e_mail_reader_get_action (reader, action_name);
3478 	gtk_action_set_sensitive (action, sensitive);
3479 
3480 	action_name = "mail-mark-unimportant";
3481 	sensitive = selection_has_important_messages;
3482 	action = e_mail_reader_get_action (reader, action_name);
3483 	gtk_action_set_sensitive (action, sensitive);
3484 
3485 	action_name = "mail-mark-unread";
3486 	sensitive = selection_has_read_messages;
3487 	action = e_mail_reader_get_action (reader, action_name);
3488 	gtk_action_set_sensitive (action, sensitive);
3489 
3490 	action_name = "mail-message-edit";
3491 	sensitive = have_enabled_account && single_message_selected;
3492 	action = e_mail_reader_get_action (reader, action_name);
3493 	gtk_action_set_sensitive (action, sensitive);
3494 
3495 	action_name = "mail-message-new";
3496 	sensitive = have_enabled_account;
3497 	action = e_mail_reader_get_action (reader, action_name);
3498 	gtk_action_set_sensitive (action, sensitive);
3499 
3500 	action_name = "mail-message-open";
3501 	sensitive = any_messages_selected;
3502 	action = e_mail_reader_get_action (reader, action_name);
3503 	gtk_action_set_sensitive (action, sensitive);
3504 
3505 	action_name = "mail-goto-folder";
3506 	sensitive = e_mail_reader_get_enable_show_folder (reader);
3507 	action = e_mail_reader_get_action (reader, action_name);
3508 	gtk_action_set_sensitive (action, sensitive);
3509 	gtk_action_set_visible (action, sensitive);
3510 
3511 	action_name = "mail-goto-nexttab";
3512 	action = e_mail_reader_get_action (reader, action_name);
3513 	gtk_action_set_sensitive (action, TRUE);
3514 	gtk_action_set_visible (action, FALSE);
3515 
3516 	action_name = "mail-goto-prevtab";
3517 	action = e_mail_reader_get_action (reader, action_name);
3518 	gtk_action_set_sensitive (action, TRUE);
3519 	gtk_action_set_visible (action, FALSE);
3520 
3521 	action_name = "mail-close-tab";
3522 	action = e_mail_reader_get_action (reader, action_name);
3523 	gtk_action_set_sensitive (action, TRUE);
3524 	gtk_action_set_visible (action, FALSE);
3525 
3526 	action_name = "mail-move";
3527 	sensitive = any_messages_selected;
3528 	action = e_mail_reader_get_action (reader, action_name);
3529 	gtk_action_set_sensitive (action, sensitive);
3530 
3531 	action_name = "mail-next";
3532 	sensitive = any_messages_selected && !last_message_selected;
3533 	action = e_mail_reader_get_action (reader, action_name);
3534 	gtk_action_set_sensitive (action, sensitive);
3535 
3536 	action_name = "mail-next-important";
3537 	sensitive = single_message_selected;
3538 	action = e_mail_reader_get_action (reader, action_name);
3539 	gtk_action_set_sensitive (action, sensitive);
3540 
3541 	action_name = "mail-next-thread";
3542 	sensitive = single_message_selected && !last_message_selected;
3543 	action = e_mail_reader_get_action (reader, action_name);
3544 	gtk_action_set_sensitive (action, sensitive);
3545 
3546 	action_name = "mail-next-unread";
3547 	sensitive = any_messages_selected;
3548 	action = e_mail_reader_get_action (reader, action_name);
3549 	gtk_action_set_sensitive (action, sensitive);
3550 
3551 	action_name = "mail-previous";
3552 	sensitive = any_messages_selected && !first_message_selected;
3553 	action = e_mail_reader_get_action (reader, action_name);
3554 	gtk_action_set_sensitive (action, sensitive);
3555 
3556 	action_name = "mail-previous-important";
3557 	sensitive = single_message_selected;
3558 	action = e_mail_reader_get_action (reader, action_name);
3559 	gtk_action_set_sensitive (action, sensitive);
3560 
3561 	action_name = "mail-previous-unread";
3562 	sensitive = any_messages_selected;
3563 	action = e_mail_reader_get_action (reader, action_name);
3564 	gtk_action_set_sensitive (action, sensitive);
3565 
3566 	action_name = "mail-previous-thread";
3567 	sensitive = any_messages_selected && !first_message_selected;
3568 	action = e_mail_reader_get_action (reader, action_name);
3569 	gtk_action_set_sensitive (action, sensitive);
3570 
3571 	action_name = "mail-print";
3572 	sensitive = single_message_selected;
3573 	action = e_mail_reader_get_action (reader, action_name);
3574 	gtk_action_set_sensitive (action, sensitive);
3575 
3576 	action_name = "mail-print-preview";
3577 	sensitive = single_message_selected;
3578 	action = e_mail_reader_get_action (reader, action_name);
3579 	gtk_action_set_sensitive (action, sensitive);
3580 
3581 	action_name = "mail-redirect";
3582 	sensitive = have_enabled_account && single_message_selected;
3583 	action = e_mail_reader_get_action (reader, action_name);
3584 	gtk_action_set_sensitive (action, sensitive);
3585 
3586 	action_name = "mail-remove-attachments";
3587 	sensitive = any_messages_selected && selection_has_attachment_messages;
3588 	action = e_mail_reader_get_action (reader, action_name);
3589 	gtk_action_set_sensitive (action, sensitive);
3590 
3591 	action_name = "mail-remove-duplicates";
3592 	sensitive = multiple_messages_selected;
3593 	action = e_mail_reader_get_action (reader, action_name);
3594 	gtk_action_set_sensitive (action, sensitive);
3595 
3596 	action_name = "mail-reply-all";
3597 	sensitive = have_enabled_account && single_message_selected;
3598 	action = e_mail_reader_get_action (reader, action_name);
3599 	gtk_action_set_sensitive (action, sensitive);
3600 
3601 	action_name = "mail-reply-group";
3602 	sensitive = have_enabled_account && single_message_selected;
3603 	action = e_mail_reader_get_action (reader, action_name);
3604 	gtk_action_set_sensitive (action, sensitive);
3605 
3606 	action_name = "mail-reply-group-menu";
3607 	sensitive = have_enabled_account && any_messages_selected;
3608 	action = e_mail_reader_get_action (reader, action_name);
3609 	gtk_action_set_sensitive (action, sensitive);
3610 
3611 	action_name = "mail-reply-list";
3612 	sensitive = have_enabled_account && single_message_selected &&
3613 		selection_is_mailing_list;
3614 	action = e_mail_reader_get_action (reader, action_name);
3615 	gtk_action_set_sensitive (action, sensitive);
3616 
3617 	action_name = "mail-reply-sender";
3618 	sensitive = have_enabled_account && single_message_selected;
3619 	action = e_mail_reader_get_action (reader, action_name);
3620 	gtk_action_set_sensitive (action, sensitive);
3621 
3622 	action_name = "mail-save-as";
3623 	sensitive = any_messages_selected;
3624 	action = e_mail_reader_get_action (reader, action_name);
3625 	gtk_action_set_sensitive (action, sensitive);
3626 
3627 	action_name = "mail-show-source";
3628 	sensitive = single_message_selected;
3629 	action = e_mail_reader_get_action (reader, action_name);
3630 	gtk_action_set_sensitive (action, sensitive);
3631 
3632 	action_name = "mail-undelete";
3633 	sensitive = selection_has_deleted_messages;
3634 	action = e_mail_reader_get_action (reader, action_name);
3635 	gtk_action_set_sensitive (action, sensitive);
3636 
3637 	action_name = "mail-zoom-100";
3638 	sensitive = single_message_selected;
3639 	action = e_mail_reader_get_action (reader, action_name);
3640 	gtk_action_set_sensitive (action, sensitive);
3641 
3642 	action_name = "mail-zoom-in";
3643 	sensitive = single_message_selected;
3644 	action = e_mail_reader_get_action (reader, action_name);
3645 	gtk_action_set_sensitive (action, sensitive);
3646 
3647 	action_name = "mail-zoom-out";
3648 	sensitive = single_message_selected;
3649 	action = e_mail_reader_get_action (reader, action_name);
3650 	gtk_action_set_sensitive (action, sensitive);
3651 }
3652 
3653 static void
3654 mail_reader_init_charset_actions (EMailReader *reader,
3655                                   GtkActionGroup *action_group)
3656 {
3657 	GtkRadioAction *default_action;
3658 	GSList *radio_group;
3659 
3660 	radio_group = e_charset_add_radio_actions (
3661 		action_group, "mail-charset-", NULL,
3662 		G_CALLBACK (action_mail_charset_cb), reader);
3663 
3664 	/* XXX Add a tooltip! */
3665 	default_action = gtk_radio_action_new (
3666 		"mail-charset-default", _("Default"), NULL, NULL, -1);
3667 
3668 	gtk_radio_action_set_group (default_action, radio_group);
3669 
3670 	g_signal_connect (
3671 		default_action, "changed",
3672 		G_CALLBACK (action_mail_charset_cb), reader);
3673 
3674 	gtk_action_group_add_action (
3675 		action_group, GTK_ACTION (default_action));
3676 
3677 	gtk_radio_action_set_current_value (default_action, -1);
3678 }
3679 
3680 static void
3681 e_mail_reader_default_init (EMailReaderInterface *interface)
3682 {
3683 	quark_private = g_quark_from_static_string ("e-mail-reader-private");
3684 
3685 	interface->get_alert_sink = mail_reader_get_alert_sink;
3686 	interface->get_selected_uids = mail_reader_get_selected_uids;
3687 	interface->get_folder = mail_reader_get_folder;
3688 	interface->enable_show_folder = mail_reader_get_enable_show_folder;
3689 	interface->set_folder = mail_reader_set_folder;
3690 	interface->set_message = mail_reader_set_message;
3691 	interface->open_selected_mail = e_mail_reader_open_selected;
3692 	interface->folder_loaded = mail_reader_folder_loaded;
3693 	interface->message_loaded = mail_reader_message_loaded;
3694 	interface->message_seen = mail_reader_message_seen;
3695 	interface->show_search_bar = mail_reader_show_search_bar;
3696 	interface->update_actions = mail_reader_update_actions;
3697 
3698 	g_object_interface_install_property (
3699 		interface,
3700 		g_param_spec_enum (
3701 			"forward-style",
3702 			"Forward Style",
3703 			"How to forward messages",
3704 			E_TYPE_MAIL_FORWARD_STYLE,
3705 			E_MAIL_FORWARD_STYLE_ATTACHED,
3706 			G_PARAM_READWRITE));
3707 
3708 	g_object_interface_install_property (
3709 		interface,
3710 		g_param_spec_boolean (
3711 			"group-by-threads",
3712 			"Group by Threads",
3713 			"Whether to group messages by threads",
3714 			FALSE,
3715 			G_PARAM_READWRITE));
3716 
3717 	g_object_interface_install_property (
3718 		interface,
3719 		g_param_spec_enum (
3720 			"reply-style",
3721 			"Reply Style",
3722 			"How to reply to messages",
3723 			E_TYPE_MAIL_REPLY_STYLE,
3724 			E_MAIL_REPLY_STYLE_QUOTED,
3725 			G_PARAM_READWRITE));
3726 
3727 	signals[CHANGED] = g_signal_new (
3728 		"changed",
3729 		G_OBJECT_CLASS_TYPE (interface),
3730 		G_SIGNAL_RUN_FIRST,
3731 		0, NULL, NULL,
3732 		g_cclosure_marshal_VOID__VOID,
3733 		G_TYPE_NONE, 0);
3734 
3735 	signals[FOLDER_LOADED] = g_signal_new (
3736 		"folder-loaded",
3737 		G_OBJECT_CLASS_TYPE (interface),
3738 		G_SIGNAL_RUN_FIRST,
3739 		G_STRUCT_OFFSET (EMailReaderInterface, folder_loaded),
3740 		NULL, NULL,
3741 		g_cclosure_marshal_VOID__VOID,
3742 		G_TYPE_NONE, 0);
3743 
3744 	signals[MESSAGE_LOADED] = g_signal_new (
3745 		"message-loaded",
3746 		G_OBJECT_CLASS_TYPE (interface),
3747 		G_SIGNAL_RUN_LAST,
3748 		G_STRUCT_OFFSET (EMailReaderInterface, message_loaded),
3749 		NULL, NULL,
3750 		e_marshal_VOID__STRING_OBJECT,
3751 		G_TYPE_NONE, 2,
3752 		G_TYPE_STRING,
3753 		CAMEL_TYPE_MIME_MESSAGE);
3754 
3755 	signals[MESSAGE_SEEN] = g_signal_new (
3756 		"message-seen",
3757 		G_OBJECT_CLASS_TYPE (interface),
3758 		G_SIGNAL_RUN_LAST,
3759 		G_STRUCT_OFFSET (EMailReaderInterface, message_seen),
3760 		NULL, NULL,
3761 		e_marshal_VOID__STRING_OBJECT,
3762 		G_TYPE_NONE, 2,
3763 		G_TYPE_STRING,
3764 		CAMEL_TYPE_MIME_MESSAGE);
3765 
3766 	signals[SHOW_SEARCH_BAR] = g_signal_new (
3767 		"show-search-bar",
3768 		G_OBJECT_CLASS_TYPE (interface),
3769 		G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
3770 		G_STRUCT_OFFSET (EMailReaderInterface, show_search_bar),
3771 		NULL, NULL,
3772 		g_cclosure_marshal_VOID__VOID,
3773 		G_TYPE_NONE, 0);
3774 
3775 	signals[SHOW_FOLDER] = g_signal_new (
3776 		"show-folder",
3777 		G_OBJECT_CLASS_TYPE (interface),
3778 		G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
3779 		0,
3780 		NULL, NULL,
3781 		g_cclosure_marshal_VOID__VOID,
3782 		G_TYPE_NONE, 0);
3783 
3784 	signals[SHOW_NEXTTAB] = g_signal_new (
3785 		"show-next-tab",
3786 		G_OBJECT_CLASS_TYPE (interface),
3787 		G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
3788 		0,
3789 		NULL, NULL,
3790 		g_cclosure_marshal_VOID__VOID,
3791 		G_TYPE_NONE, 0);
3792 
3793 	signals[SHOW_PREVTAB] = g_signal_new (
3794 		"show-previous-tab",
3795 		G_OBJECT_CLASS_TYPE (interface),
3796 		G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
3797 		0,
3798 		NULL, NULL,
3799 		g_cclosure_marshal_VOID__VOID,
3800 		G_TYPE_NONE, 0);
3801 
3802 	signals[CLOSE_TAB] = g_signal_new (
3803 		"close-tab",
3804 		G_OBJECT_CLASS_TYPE (interface),
3805 		G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
3806 		0,
3807 		NULL, NULL,
3808 		g_cclosure_marshal_VOID__VOID,
3809 		G_TYPE_NONE, 0);
3810 
3811 	signals[UPDATE_ACTIONS] = g_signal_new (
3812 		"update-actions",
3813 		G_OBJECT_CLASS_TYPE (interface),
3814 		G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
3815 		G_STRUCT_OFFSET (EMailReaderInterface, update_actions),
3816 		NULL, NULL,
3817 		g_cclosure_marshal_VOID__UINT,
3818 		G_TYPE_NONE, 1,
3819 		G_TYPE_UINT);
3820 }
3821 
3822 void
3823 e_mail_reader_init (EMailReader *reader,
3824                     gboolean init_actions,
3825                     gboolean connect_signals)
3826 {
3827 	EMenuToolAction *menu_tool_action;
3828 	GtkActionGroup *action_group;
3829 	GtkWidget *message_list;
3830 	GtkAction *action;
3831 	gboolean sensitive;
3832 	const gchar *action_name;
3833 	EMailDisplay *display;
3834 	GSettings *settings;
3835 
3836 	g_return_if_fail (E_IS_MAIL_READER (reader));
3837 
3838 	message_list = e_mail_reader_get_message_list (reader);
3839 	display = e_mail_reader_get_mail_display (reader);
3840 
3841 	/* Initialize a private struct. */
3842 	g_object_set_qdata_full (
3843 		G_OBJECT (reader), quark_private,
3844 		g_slice_new0 (EMailReaderPrivate),
3845 		(GDestroyNotify) mail_reader_private_free);
3846 
3847 	if (!init_actions)
3848 		goto connect_signals;
3849 
3850 	/* Add the "standard" EMailReader actions. */
3851 
3852 	action_group = e_mail_reader_get_action_group (
3853 		reader, E_MAIL_READER_ACTION_GROUP_STANDARD);
3854 
3855 	/* The "mail-forward" action is special: it uses a GtkMenuToolButton
3856 	 * for its toolbar item type.  So we have to create it separately. */
3857 
3858 	menu_tool_action = e_menu_tool_action_new (
3859 		"mail-forward", _("_Forward"),
3860 		_("Forward the selected message to someone"), NULL);
3861 
3862 	gtk_action_set_icon_name (
3863 		GTK_ACTION (menu_tool_action), "mail-forward");
3864 
3865 	g_signal_connect (
3866 		menu_tool_action, "activate",
3867 		G_CALLBACK (action_mail_forward_cb), reader);
3868 
3869 	gtk_action_group_add_action_with_accel (
3870 		action_group, GTK_ACTION (menu_tool_action), "<Control>f");
3871 
3872 	/* Likewise the "mail-reply-group" action. */
3873 
3874         /* For Translators: "Group Reply" will reply either to a mailing list
3875 	   (if possible and if that configuration option is enabled), or else
3876 	   it will reply to all. The word "Group" was chosen because it covers
3877 	   either of those, without too strongly implying one or the other. */
3878 	menu_tool_action = e_menu_tool_action_new (
3879 		"mail-reply-group", _("Group Reply"),
3880 		_("Reply to the mailing list, or to all recipients"), NULL);
3881 
3882 	gtk_action_set_icon_name (
3883 		GTK_ACTION (menu_tool_action), "mail-reply-all");
3884 
3885 	g_signal_connect (
3886 		menu_tool_action, "activate",
3887 		G_CALLBACK (action_mail_reply_group_cb), reader);
3888 
3889 	gtk_action_group_add_action_with_accel (
3890 		action_group, GTK_ACTION (menu_tool_action), "<Control>g");
3891 
3892 	/* Add the other actions the normal way. */
3893 	gtk_action_group_add_actions (
3894 		action_group, mail_reader_entries,
3895 		G_N_ELEMENTS (mail_reader_entries), reader);
3896 	e_action_group_add_popup_actions (
3897 		action_group, mail_reader_popup_entries,
3898 		G_N_ELEMENTS (mail_reader_popup_entries));
3899 	gtk_action_group_add_toggle_actions (
3900 		action_group, mail_reader_toggle_entries,
3901 		G_N_ELEMENTS (mail_reader_toggle_entries), reader);
3902 
3903 	mail_reader_init_charset_actions (reader, action_group);
3904 
3905 	/* Add EMailReader actions for Search Folders.  The action group
3906 	 * should be made invisible if Search Folders are disabled. */
3907 
3908 	action_group = e_mail_reader_get_action_group (
3909 		reader, E_MAIL_READER_ACTION_GROUP_SEARCH_FOLDERS);
3910 
3911 	gtk_action_group_add_actions (
3912 		action_group, mail_reader_search_folder_entries,
3913 		G_N_ELEMENTS (mail_reader_search_folder_entries), reader);
3914 
3915 	display = e_mail_reader_get_mail_display (reader);
3916 
3917 	/* Bind GObject properties to GSettings keys. */
3918 
3919 	settings = g_settings_new ("org.gnome.evolution.mail");
3920 
3921 	action_name = "mail-caret-mode";
3922 	action = e_mail_reader_get_action (reader, action_name);
3923 	g_settings_bind (
3924 		settings, "caret-mode",
3925 		action, "active", G_SETTINGS_BIND_DEFAULT);
3926 
3927 	action_name = "mail-show-all-headers";
3928 	action = e_mail_reader_get_action (reader, action_name);
3929 	g_settings_bind (
3930 		settings, "show-all-headers",
3931 		action, "active", G_SETTINGS_BIND_DEFAULT);
3932 
3933 	/* mode change when viewing message source is ignored */
3934 	if (e_mail_display_get_mode (display) == E_MAIL_FORMATTER_MODE_SOURCE ||
3935 	    e_mail_display_get_mode (display) == E_MAIL_FORMATTER_MODE_RAW) {
3936 		gtk_action_set_sensitive (action, FALSE);
3937 		gtk_action_set_visible (action, FALSE);
3938 	}
3939 
3940 	g_object_unref (settings);
3941 
3942 	/* Fine tuning. */
3943 
3944 	action_name = "mail-delete";
3945 	action = e_mail_reader_get_action (reader, action_name);
3946 	gtk_action_set_short_label (action, _("Delete"));
3947 
3948 	action_name = "mail-forward";
3949 	action = e_mail_reader_get_action (reader, action_name);
3950 	gtk_action_set_is_important (action, TRUE);
3951 
3952 	action_name = "mail-reply-group";
3953 	action = e_mail_reader_get_action (reader, action_name);
3954 	gtk_action_set_is_important (action, TRUE);
3955 
3956 	action_name = "mail-goto-folder";
3957 	action = e_mail_reader_get_action (reader, action_name);
3958 	sensitive = e_mail_reader_get_enable_show_folder (reader);
3959 	gtk_action_set_sensitive (action, sensitive);
3960 	gtk_action_set_visible (action, FALSE);
3961 
3962 	action_name = "mail-goto-nexttab";
3963 	action = e_mail_reader_get_action (reader, action_name);
3964 	gtk_action_set_sensitive (action, TRUE);
3965 	gtk_action_set_visible (action, FALSE);
3966 
3967 	action_name = "mail-goto-prevtab";
3968 	action = e_mail_reader_get_action (reader, action_name);
3969 	gtk_action_set_sensitive (action, TRUE);
3970 	gtk_action_set_visible (action, FALSE);
3971 
3972 	action_name = "mail-close-tab";
3973 	action = e_mail_reader_get_action (reader, action_name);
3974 	gtk_action_set_sensitive (action, TRUE);
3975 	gtk_action_set_visible (action, FALSE);
3976 
3977 	action_name = "mail-next";
3978 	action = e_mail_reader_get_action (reader, action_name);
3979 	gtk_action_set_short_label (action, _("Next"));
3980 
3981 	action_name = "mail-previous";
3982 	action = e_mail_reader_get_action (reader, action_name);
3983 	gtk_action_set_short_label (action, _("Previous"));
3984 
3985 	action_name = "mail-reply-all";
3986 	action = e_mail_reader_get_action (reader, action_name);
3987 	gtk_action_set_is_important (action, TRUE);
3988 
3989 	action_name = "mail-reply-sender";
3990 	action = e_mail_reader_get_action (reader, action_name);
3991 	gtk_action_set_is_important (action, TRUE);
3992 	gtk_action_set_short_label (action, _("Reply"));
3993 
3994 	action_name = "add-to-address-book";
3995 	action = e_mail_display_get_action (display, action_name);
3996 	g_signal_connect (
3997 		action, "activate",
3998 		G_CALLBACK (action_add_to_address_book_cb), reader);
3999 
4000 	action_name = "send-reply";
4001 	action = e_mail_display_get_action (display, action_name);
4002 	g_signal_connect (
4003 		action, "activate",
4004 		G_CALLBACK (action_mail_reply_recipient_cb), reader);
4005 
4006 	action_name = "search-folder-recipient";
4007 	action = e_mail_display_get_action (display, action_name);
4008 	g_signal_connect (
4009 		action, "activate",
4010 		G_CALLBACK (action_search_folder_recipient_cb), reader);
4011 
4012 	action_name = "search-folder-sender";
4013 	action = e_mail_display_get_action (display, action_name);
4014 	g_signal_connect (
4015 		action, "activate",
4016 		G_CALLBACK (action_search_folder_sender_cb), reader);
4017 
4018 	action_name = "image-save";
4019 	action = e_mail_display_get_action (display, action_name);
4020 	g_signal_connect (
4021 		action, "activate",
4022 		G_CALLBACK (action_mail_image_save_cb), reader);
4023 
4024 #ifndef G_OS_WIN32
4025 	/* Lockdown integration. */
4026 
4027 	settings = g_settings_new ("org.gnome.desktop.lockdown");
4028 
4029 	action_name = "mail-print";
4030 	action = e_mail_reader_get_action (reader, action_name);
4031 	g_settings_bind (
4032 		settings, "disable-printing",
4033 		action, "visible",
4034 		G_SETTINGS_BIND_GET |
4035 		G_SETTINGS_BIND_NO_SENSITIVITY |
4036 		G_SETTINGS_BIND_INVERT_BOOLEAN);
4037 
4038 	action_name = "mail-print-preview";
4039 	action = e_mail_reader_get_action (reader, action_name);
4040 	g_settings_bind (
4041 		settings, "disable-printing",
4042 		action, "visible",
4043 		G_SETTINGS_BIND_GET |
4044 		G_SETTINGS_BIND_NO_SENSITIVITY |
4045 		G_SETTINGS_BIND_INVERT_BOOLEAN);
4046 
4047 	action_name = "mail-save-as";
4048 	action = e_mail_reader_get_action (reader, action_name);
4049 	g_settings_bind (
4050 		settings, "disable-save-to-disk",
4051 		action, "visible",
4052 		G_SETTINGS_BIND_GET |
4053 		G_SETTINGS_BIND_NO_SENSITIVITY |
4054 		G_SETTINGS_BIND_INVERT_BOOLEAN);
4055 
4056 	g_object_unref (settings);
4057 #endif
4058 
4059 	/* Bind properties. */
4060 
4061 	action_name = "mail-caret-mode";
4062 	action = e_mail_reader_get_action (reader, action_name);
4063 
4064 	g_object_bind_property (
4065 		action, "active",
4066 		display, "caret-mode",
4067 		G_BINDING_BIDIRECTIONAL |
4068 		G_BINDING_SYNC_CREATE);
4069 
4070 connect_signals:
4071 
4072 	if (!connect_signals)
4073 		return;
4074 
4075 	/* Connect signals. */
4076 	g_signal_connect_swapped (
4077 		display, "key-press-event",
4078 		G_CALLBACK (mail_reader_key_press_event_cb), reader);
4079 
4080 	g_signal_connect_swapped (
4081 		message_list, "message-selected",
4082 		G_CALLBACK (mail_reader_message_selected_cb), reader);
4083 
4084 	/* re-schedule mark-as-seen,... */
4085 	g_signal_connect_swapped (
4086 		message_list, "cursor-change",
4087 		G_CALLBACK (mail_reader_message_cursor_change_cb), reader);
4088 
4089 	/* but do not mark-as-seen if... */
4090 	g_signal_connect_swapped (
4091 		message_list, "tree-drag-begin",
4092 		G_CALLBACK (discard_timeout_mark_seen_cb), reader);
4093 
4094 	g_signal_connect_swapped (
4095 		message_list, "tree-drag-end",
4096 		G_CALLBACK (discard_timeout_mark_seen_cb), reader);
4097 
4098 	g_signal_connect_swapped (
4099 		message_list, "right-click",
4100 		G_CALLBACK (discard_timeout_mark_seen_cb), reader);
4101 
4102 	g_signal_connect_swapped (
4103 		message_list, "message-list-built",
4104 		G_CALLBACK (mail_reader_emit_folder_loaded), reader);
4105 
4106 	g_signal_connect_swapped (
4107 		message_list, "double-click",
4108 		G_CALLBACK (mail_reader_double_click_cb), reader);
4109 
4110 	g_signal_connect_swapped (
4111 		message_list, "key-press",
4112 		G_CALLBACK (mail_reader_key_press_cb), reader);
4113 
4114 	g_signal_connect_swapped (
4115 		message_list, "selection-change",
4116 		G_CALLBACK (e_mail_reader_changed), reader);
4117 }
4118 
4119 void
4120 e_mail_reader_changed (EMailReader *reader)
4121 {
4122 	g_return_if_fail (E_IS_MAIL_READER (reader));
4123 
4124 	g_signal_emit (reader, signals[CHANGED], 0);
4125 }
4126 
4127 guint32
4128 e_mail_reader_check_state (EMailReader *reader)
4129 {
4130 	EShell *shell;
4131 	GPtrArray *uids;
4132 	CamelFolder *folder;
4133 	CamelStore *store = NULL;
4134 	EMailBackend *backend;
4135 	ESourceRegistry *registry;
4136 	EMailSession *mail_session;
4137 	EMailAccountStore *account_store;
4138 	const gchar *tag;
4139 	gboolean can_clear_flags = FALSE;
4140 	gboolean can_flag_completed = FALSE;
4141 	gboolean can_flag_for_followup = FALSE;
4142 	gboolean has_attachments = FALSE;
4143 	gboolean has_deleted = FALSE;
4144 	gboolean has_important = FALSE;
4145 	gboolean has_junk = FALSE;
4146 	gboolean has_not_junk = FALSE;
4147 	gboolean has_read = FALSE;
4148 	gboolean has_undeleted = FALSE;
4149 	gboolean has_unimportant = FALSE;
4150 	gboolean has_unread = FALSE;
4151 	gboolean have_enabled_account = FALSE;
4152 	gboolean drafts_or_outbox = FALSE;
4153 	gboolean store_supports_vjunk = FALSE;
4154 	gboolean is_mailing_list;
4155 	gboolean is_junk_folder = FALSE;
4156 	guint32 state = 0;
4157 	guint ii;
4158 
4159 	g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
4160 
4161 	backend = e_mail_reader_get_backend (reader);
4162 	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
4163 	registry = e_shell_get_registry (shell);
4164 	mail_session = e_mail_backend_get_session (backend);
4165 	account_store = e_mail_ui_session_get_account_store (E_MAIL_UI_SESSION (mail_session));
4166 
4167 	folder = e_mail_reader_get_folder (reader);
4168 	uids = e_mail_reader_get_selected_uids (reader);
4169 
4170 	if (folder != NULL) {
4171 		store = camel_folder_get_parent_store (folder);
4172 		store_supports_vjunk = (store->flags & CAMEL_STORE_VJUNK);
4173 		is_junk_folder =
4174 			(folder->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0;
4175 		drafts_or_outbox =
4176 			em_utils_folder_is_drafts (registry, folder) ||
4177 			em_utils_folder_is_outbox (registry, folder);
4178 	}
4179 
4180 	/* Initialize this flag based on whether there are any
4181 	 * messages selected.  We will update it in the loop. */
4182 	is_mailing_list = (uids->len > 0);
4183 
4184 	for (ii = 0; ii < uids->len; ii++) {
4185 		CamelMessageInfo *info;
4186 		const gchar *string;
4187 		guint32 flags;
4188 
4189 		info = camel_folder_get_message_info (
4190 			folder, uids->pdata[ii]);
4191 		if (info == NULL)
4192 			continue;
4193 
4194 		flags = camel_message_info_flags (info);
4195 
4196 		if (flags & CAMEL_MESSAGE_SEEN)
4197 			has_read = TRUE;
4198 		else
4199 			has_unread = TRUE;
4200 
4201 		if (flags & CAMEL_MESSAGE_ATTACHMENTS)
4202 			has_attachments = TRUE;
4203 
4204 		if (drafts_or_outbox) {
4205 			has_junk = FALSE;
4206 			has_not_junk = FALSE;
4207 		} else if (store_supports_vjunk) {
4208 			guint32 bitmask;
4209 
4210 			/* XXX Strictly speaking, this logic is correct.
4211 			 *     Problem is there's nothing in the message
4212 			 *     list that indicates whether a message is
4213 			 *     already marked "Not Junk".  So the user may
4214 			 *     think the "Not Junk" button is enabling and
4215 			 *     disabling itself randomly as he reads mail. */
4216 
4217 			if (flags & CAMEL_MESSAGE_JUNK)
4218 				has_junk = TRUE;
4219 			if (flags & CAMEL_MESSAGE_NOTJUNK)
4220 				has_not_junk = TRUE;
4221 
4222 			bitmask = CAMEL_MESSAGE_JUNK | CAMEL_MESSAGE_NOTJUNK;
4223 
4224 			/* If neither junk flag is set, the
4225 			 * message can be marked either way. */
4226 			if ((flags & bitmask) == 0) {
4227 				has_junk = TRUE;
4228 				has_not_junk = TRUE;
4229 			}
4230 
4231 		} else {
4232 			has_junk = TRUE;
4233 			has_not_junk = TRUE;
4234 		}
4235 
4236 		if (flags & CAMEL_MESSAGE_DELETED)
4237 			has_deleted = TRUE;
4238 		else
4239 			has_undeleted = TRUE;
4240 
4241 		if (flags & CAMEL_MESSAGE_FLAGGED)
4242 			has_important = TRUE;
4243 		else
4244 			has_unimportant = TRUE;
4245 
4246 		tag = camel_message_info_user_tag (info, "follow-up");
4247 		if (tag != NULL && *tag != '\0') {
4248 			can_clear_flags = TRUE;
4249 			tag = camel_message_info_user_tag (
4250 				info, "completed-on");
4251 			if (tag == NULL || *tag == '\0')
4252 				can_flag_completed = TRUE;
4253 		} else
4254 			can_flag_for_followup = TRUE;
4255 
4256 		string = camel_message_info_mlist (info);
4257 		is_mailing_list &= (string != NULL && *string != '\0');
4258 
4259 		camel_folder_free_message_info (folder, info);
4260 	}
4261 
4262 	have_enabled_account = e_mail_account_store_have_enabled_service (account_store, CAMEL_TYPE_STORE);
4263 
4264 	if (have_enabled_account)
4265 		state |= E_MAIL_READER_HAVE_ENABLED_ACCOUNT;
4266 	if (uids->len == 1)
4267 		state |= E_MAIL_READER_SELECTION_SINGLE;
4268 	if (uids->len > 1)
4269 		state |= E_MAIL_READER_SELECTION_MULTIPLE;
4270 	if (!drafts_or_outbox && uids->len == 1)
4271 		state |= E_MAIL_READER_SELECTION_CAN_ADD_SENDER;
4272 	if (can_clear_flags)
4273 		state |= E_MAIL_READER_SELECTION_FLAG_CLEAR;
4274 	if (can_flag_completed)
4275 		state |= E_MAIL_READER_SELECTION_FLAG_COMPLETED;
4276 	if (can_flag_for_followup)
4277 		state |= E_MAIL_READER_SELECTION_FLAG_FOLLOWUP;
4278 	if (has_attachments)
4279 		state |= E_MAIL_READER_SELECTION_HAS_ATTACHMENTS;
4280 	if (has_deleted)
4281 		state |= E_MAIL_READER_SELECTION_HAS_DELETED;
4282 	if (has_important)
4283 		state |= E_MAIL_READER_SELECTION_HAS_IMPORTANT;
4284 	if (has_junk)
4285 		state |= E_MAIL_READER_SELECTION_HAS_JUNK;
4286 	if (has_not_junk)
4287 		state |= E_MAIL_READER_SELECTION_HAS_NOT_JUNK;
4288 	if (has_read)
4289 		state |= E_MAIL_READER_SELECTION_HAS_READ;
4290 	if (has_undeleted)
4291 		state |= E_MAIL_READER_SELECTION_HAS_UNDELETED;
4292 	if (has_unimportant)
4293 		state |= E_MAIL_READER_SELECTION_HAS_UNIMPORTANT;
4294 	if (has_unread)
4295 		state |= E_MAIL_READER_SELECTION_HAS_UNREAD;
4296 	if (is_mailing_list)
4297 		state |= E_MAIL_READER_SELECTION_IS_MAILING_LIST;
4298 	if (is_junk_folder)
4299 		state |= E_MAIL_READER_FOLDER_IS_JUNK;
4300 
4301 	em_utils_uids_free (uids);
4302 
4303 	return state;
4304 }
4305 
4306 EActivity *
4307 e_mail_reader_new_activity (EMailReader *reader)
4308 {
4309 	EActivity *activity;
4310 	EMailBackend *backend;
4311 	EAlertSink *alert_sink;
4312 	GCancellable *cancellable;
4313 
4314 	g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4315 
4316 	activity = e_activity_new ();
4317 
4318 	alert_sink = e_mail_reader_get_alert_sink (reader);
4319 	e_activity_set_alert_sink (activity, alert_sink);
4320 
4321 	cancellable = camel_operation_new ();
4322 	e_activity_set_cancellable (activity, cancellable);
4323 	g_object_unref (cancellable);
4324 
4325 	backend = e_mail_reader_get_backend (reader);
4326 	e_shell_backend_add_activity (E_SHELL_BACKEND (backend), activity);
4327 
4328 	return activity;
4329 }
4330 
4331 void
4332 e_mail_reader_update_actions (EMailReader *reader,
4333                               guint32 state)
4334 {
4335 	g_return_if_fail (E_IS_MAIL_READER (reader));
4336 
4337 	g_signal_emit (reader, signals[UPDATE_ACTIONS], 0, state);
4338 }
4339 
4340 GtkAction *
4341 e_mail_reader_get_action (EMailReader *reader,
4342                           const gchar *action_name)
4343 {
4344 	GtkAction *action = NULL;
4345 	gint ii;
4346 
4347 	g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4348 	g_return_val_if_fail (action_name != NULL, NULL);
4349 
4350 	for (ii = 0; ii < E_MAIL_READER_NUM_ACTION_GROUPS; ii++) {
4351 		GtkActionGroup *group;
4352 
4353 		group = e_mail_reader_get_action_group (reader, ii);
4354 		action = gtk_action_group_get_action (group, action_name);
4355 
4356 		if (action != NULL)
4357 			break;
4358 	}
4359 
4360 	if (action == NULL)
4361 		g_critical (
4362 			"%s: action '%s' not found", G_STRFUNC, action_name);
4363 
4364 	return action;
4365 }
4366 
4367 GtkActionGroup *
4368 e_mail_reader_get_action_group (EMailReader *reader,
4369                                 EMailReaderActionGroup group)
4370 {
4371 	EMailReaderInterface *interface;
4372 
4373 	g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4374 
4375 	interface = E_MAIL_READER_GET_INTERFACE (reader);
4376 	g_return_val_if_fail (interface->get_action_group != NULL, NULL);
4377 
4378 	return interface->get_action_group (reader, group);
4379 }
4380 
4381 EAlertSink *
4382 e_mail_reader_get_alert_sink (EMailReader *reader)
4383 {
4384 	EMailReaderInterface *interface;
4385 
4386 	g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4387 
4388 	interface = E_MAIL_READER_GET_INTERFACE (reader);
4389 	g_return_val_if_fail (interface->get_alert_sink != NULL, NULL);
4390 
4391 	return interface->get_alert_sink (reader);
4392 }
4393 
4394 EMailBackend *
4395 e_mail_reader_get_backend (EMailReader *reader)
4396 {
4397 	EMailReaderInterface *interface;
4398 
4399 	g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4400 
4401 	interface = E_MAIL_READER_GET_INTERFACE (reader);
4402 	g_return_val_if_fail (interface->get_backend != NULL, NULL);
4403 
4404 	return interface->get_backend (reader);
4405 }
4406 
4407 EMailDisplay *
4408 e_mail_reader_get_mail_display (EMailReader *reader)
4409 {
4410 	EMailReaderInterface *interface;
4411 
4412 	g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4413 
4414 	interface = E_MAIL_READER_GET_INTERFACE (reader);
4415 	g_return_val_if_fail (interface->get_mail_display != NULL, NULL);
4416 
4417 	return interface->get_mail_display (reader);
4418 }
4419 
4420 gboolean
4421 e_mail_reader_get_hide_deleted (EMailReader *reader)
4422 {
4423 	EMailReaderInterface *interface;
4424 
4425 	g_return_val_if_fail (E_IS_MAIL_READER (reader), FALSE);
4426 
4427 	interface = E_MAIL_READER_GET_INTERFACE (reader);
4428 	g_return_val_if_fail (interface->get_hide_deleted != NULL, FALSE);
4429 
4430 	return interface->get_hide_deleted (reader);
4431 }
4432 
4433 GtkWidget *
4434 e_mail_reader_get_message_list (EMailReader *reader)
4435 {
4436 	EMailReaderInterface *interface;
4437 
4438 	g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4439 
4440 	interface = E_MAIL_READER_GET_INTERFACE (reader);
4441 	g_return_val_if_fail (interface->get_message_list != NULL, NULL);
4442 
4443 	return interface->get_message_list (reader);
4444 }
4445 
4446 GtkMenu *
4447 e_mail_reader_get_popup_menu (EMailReader *reader)
4448 {
4449 	EMailReaderInterface *interface;
4450 
4451 	g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4452 
4453 	interface = E_MAIL_READER_GET_INTERFACE (reader);
4454 	g_return_val_if_fail (interface->get_popup_menu != NULL, NULL);
4455 
4456 	return interface->get_popup_menu (reader);
4457 }
4458 
4459 EPreviewPane *
4460 e_mail_reader_get_preview_pane (EMailReader *reader)
4461 {
4462 	EMailReaderInterface *interface;
4463 
4464 	g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4465 
4466 	interface = E_MAIL_READER_GET_INTERFACE (reader);
4467 	g_return_val_if_fail (interface->get_preview_pane != NULL, NULL);
4468 
4469 	return interface->get_preview_pane (reader);
4470 }
4471 
4472 GPtrArray *
4473 e_mail_reader_get_selected_uids (EMailReader *reader)
4474 {
4475 	EMailReaderInterface *interface;
4476 
4477 	g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4478 
4479 	interface = E_MAIL_READER_GET_INTERFACE (reader);
4480 	g_return_val_if_fail (interface->get_selected_uids != NULL, NULL);
4481 
4482 	return interface->get_selected_uids (reader);
4483 }
4484 
4485 GtkWindow *
4486 e_mail_reader_get_window (EMailReader *reader)
4487 {
4488 	EMailReaderInterface *interface;
4489 
4490 	g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4491 
4492 	interface = E_MAIL_READER_GET_INTERFACE (reader);
4493 	g_return_val_if_fail (interface->get_window != NULL, NULL);
4494 
4495 	return interface->get_window (reader);
4496 }
4497 
4498 CamelFolder *
4499 e_mail_reader_get_folder (EMailReader *reader)
4500 {
4501 	EMailReaderInterface *interface;
4502 
4503 	g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4504 
4505 	interface = E_MAIL_READER_GET_INTERFACE (reader);
4506 	g_return_val_if_fail (interface->get_folder != NULL, NULL);
4507 
4508 	return interface->get_folder (reader);
4509 }
4510 
4511 void
4512 e_mail_reader_set_folder (EMailReader *reader,
4513                           CamelFolder *folder)
4514 {
4515 	EMailReaderInterface *interface;
4516 
4517 	g_return_if_fail (E_IS_MAIL_READER (reader));
4518 
4519 	interface = E_MAIL_READER_GET_INTERFACE (reader);
4520 	g_return_if_fail (interface->set_folder != NULL);
4521 
4522 	interface->set_folder (reader, folder);
4523 }
4524 
4525 void
4526 e_mail_reader_set_message (EMailReader *reader,
4527                            const gchar *message_uid)
4528 {
4529 	EMailReaderInterface *interface;
4530 
4531 	g_return_if_fail (E_IS_MAIL_READER (reader));
4532 
4533 	interface = E_MAIL_READER_GET_INTERFACE (reader);
4534 	g_return_if_fail (interface->set_message != NULL);
4535 
4536 	interface->set_message (reader, message_uid);
4537 }
4538 
4539 guint
4540 e_mail_reader_open_selected_mail (EMailReader *reader)
4541 {
4542 	EMailReaderInterface *interface;
4543 
4544 	g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
4545 
4546 	interface = E_MAIL_READER_GET_INTERFACE (reader);
4547 	g_return_val_if_fail (interface->open_selected_mail != NULL, 0);
4548 
4549 	return interface->open_selected_mail (reader);
4550 }
4551 
4552 EMailForwardStyle
4553 e_mail_reader_get_forward_style (EMailReader *reader)
4554 {
4555 	EMailReaderPrivate *priv;
4556 
4557 	g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
4558 
4559 	priv = E_MAIL_READER_GET_PRIVATE (reader);
4560 
4561 	return priv->forward_style;
4562 }
4563 
4564 void
4565 e_mail_reader_set_forward_style (EMailReader *reader,
4566                                  EMailForwardStyle style)
4567 {
4568 	EMailReaderPrivate *priv;
4569 
4570 	g_return_if_fail (E_IS_MAIL_READER (reader));
4571 
4572 	priv = E_MAIL_READER_GET_PRIVATE (reader);
4573 
4574 	if (priv->forward_style == style)
4575 		return;
4576 
4577 	priv->forward_style = style;
4578 
4579 	g_object_notify (G_OBJECT (reader), "forward-style");
4580 }
4581 
4582 gboolean
4583 e_mail_reader_get_group_by_threads (EMailReader *reader)
4584 {
4585 	EMailReaderPrivate *priv;
4586 
4587 	g_return_val_if_fail (E_IS_MAIL_READER (reader), FALSE);
4588 
4589 	priv = E_MAIL_READER_GET_PRIVATE (reader);
4590 
4591 	return priv->group_by_threads;
4592 }
4593 
4594 void
4595 e_mail_reader_set_group_by_threads (EMailReader *reader,
4596                                     gboolean group_by_threads)
4597 {
4598 	EMailReaderPrivate *priv;
4599 	GtkWidget *message_list;
4600 
4601 	g_return_if_fail (E_IS_MAIL_READER (reader));
4602 
4603 	priv = E_MAIL_READER_GET_PRIVATE (reader);
4604 
4605 	if (priv->group_by_threads == group_by_threads)
4606 		return;
4607 
4608 	priv->group_by_threads = group_by_threads;
4609 
4610 	/* XXX MessageList should define a property for this. */
4611 	message_list = e_mail_reader_get_message_list (reader);
4612 	message_list_set_threaded (
4613 		MESSAGE_LIST (message_list), group_by_threads);
4614 
4615 	g_object_notify (G_OBJECT (reader), "group-by-threads");
4616 }
4617 
4618 EMailReplyStyle
4619 e_mail_reader_get_reply_style (EMailReader *reader)
4620 {
4621 	EMailReaderPrivate *priv;
4622 
4623 	g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
4624 
4625 	priv = E_MAIL_READER_GET_PRIVATE (reader);
4626 
4627 	return priv->reply_style;
4628 }
4629 
4630 void
4631 e_mail_reader_set_reply_style (EMailReader *reader,
4632                                EMailReplyStyle style)
4633 {
4634 	EMailReaderPrivate *priv;
4635 
4636 	g_return_if_fail (E_IS_MAIL_READER (reader));
4637 
4638 	priv = E_MAIL_READER_GET_PRIVATE (reader);
4639 
4640 	if (priv->reply_style == style)
4641 		return;
4642 
4643 	priv->reply_style = style;
4644 
4645 	g_object_notify (G_OBJECT (reader), "reply-style");
4646 }
4647 
4648 void
4649 e_mail_reader_create_charset_menu (EMailReader *reader,
4650                                    GtkUIManager *ui_manager,
4651                                    guint merge_id)
4652 {
4653 	GtkAction *action;
4654 	const gchar *action_name;
4655 	const gchar *path;
4656 	GSList *list;
4657 
4658 	g_return_if_fail (E_IS_MAIL_READER (reader));
4659 	g_return_if_fail (GTK_IS_UI_MANAGER (ui_manager));
4660 
4661 	action_name = "mail-charset-default";
4662 	action = e_mail_reader_get_action (reader, action_name);
4663 	g_return_if_fail (action != NULL);
4664 
4665 	list = gtk_radio_action_get_group (GTK_RADIO_ACTION (action));
4666 	list = g_slist_copy (list);
4667 	list = g_slist_remove (list, action);
4668 	list = g_slist_sort (list, (GCompareFunc) e_action_compare_by_label);
4669 
4670 	path = "/main-menu/view-menu/mail-message-view-actions/mail-encoding-menu";
4671 
4672 	while (list != NULL) {
4673 		action = list->data;
4674 
4675 		gtk_ui_manager_add_ui (
4676 			ui_manager, merge_id, path,
4677 			gtk_action_get_name (action),
4678 			gtk_action_get_name (action),
4679 			GTK_UI_MANAGER_AUTO, FALSE);
4680 
4681 		list = g_slist_delete_link (list, list);
4682 	}
4683 
4684 	gtk_ui_manager_ensure_update (ui_manager);
4685 }
4686 
4687 void
4688 e_mail_reader_show_search_bar (EMailReader *reader)
4689 {
4690 	g_return_if_fail (E_IS_MAIL_READER (reader));
4691 
4692 	g_signal_emit (reader, signals[SHOW_SEARCH_BAR], 0);
4693 }
4694 
4695 void
4696 e_mail_reader_enable_show_folder (EMailReader *reader)
4697 {
4698 	CamelFolder *folder;
4699 	GtkAction *action;
4700 	const gchar *action_name;
4701 	const gchar *full_name;
4702 	gboolean sensitive;
4703 	gchar *label;
4704 
4705 	g_return_if_fail (E_IS_MAIL_READER (reader));
4706 
4707 	folder = e_mail_reader_get_folder (reader);
4708 
4709 	full_name = camel_folder_get_full_name (folder);
4710 	label = g_strdup_printf (_("Folder '%s'"), full_name);
4711 
4712 	action_name = "mail-goto-folder";
4713 	action = e_mail_reader_get_action (reader, action_name);
4714 	sensitive = e_mail_reader_get_enable_show_folder (reader);
4715 	gtk_action_set_label (action, label);
4716 	gtk_action_set_visible (action, TRUE);
4717 	gtk_action_set_sensitive (action, sensitive);
4718 
4719 	g_free (label);
4720 }
4721 
4722 gboolean
4723 e_mail_reader_get_enable_show_folder (EMailReader *reader)
4724 {
4725 	EMailReaderInterface *interface;
4726 
4727 	g_return_val_if_fail (E_IS_MAIL_READER (reader), FALSE);
4728 
4729 	interface = E_MAIL_READER_GET_INTERFACE (reader);
4730 	g_return_val_if_fail (interface->enable_show_folder != NULL, FALSE);
4731 
4732 	return interface->enable_show_folder (reader);
4733 }
4734 
4735 void
4736 e_mail_reader_avoid_next_mark_as_seen (EMailReader *reader)
4737 {
4738 	EMailReaderPrivate *priv;
4739 	MessageList *message_list;
4740 
4741 	g_return_if_fail (reader != NULL);
4742 
4743 	priv = E_MAIL_READER_GET_PRIVATE (reader);
4744 	g_return_if_fail (priv != NULL);
4745 
4746 	message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
4747 	g_return_if_fail (message_list != NULL);
4748 
4749 	priv->avoid_next_mark_as_seen = TRUE;
4750 }