1 /*
2  * e-mail-browser.c
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; if not, see <http://www.gnu.org/licenses/>.
15  *
16  *
17  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
18  *
19  */
20 
21 #include "evolution-config.h"
22 
23 #include "e-mail-browser.h"
24 
25 #include <string.h>
26 #include <glib/gi18n.h>
27 
28 #include <shell/e-shell.h>
29 #include <shell/e-shell-utils.h>
30 
31 #include <em-format/e-mail-formatter-enumtypes.h>
32 
33 #include "e-mail-reader.h"
34 #include "e-mail-reader-utils.h"
35 #include "em-folder-tree-model.h"
36 #include "message-list.h"
37 
38 #define E_MAIL_BROWSER_GET_PRIVATE(obj) \
39 	(G_TYPE_INSTANCE_GET_PRIVATE \
40 	((obj), E_TYPE_MAIL_BROWSER, EMailBrowserPrivate))
41 
42 #define ACTION_GROUP_STANDARD		"action-group-standard"
43 #define ACTION_GROUP_SEARCH_FOLDERS	"action-group-search-folders"
44 #define ACTION_GROUP_LABELS		"action-group-labels"
45 
46 struct _EMailBrowserPrivate {
47 	EMailBackend *backend;
48 	GtkUIManager *ui_manager;
49 	EFocusTracker *focus_tracker;
50 
51 	EMailFormatterMode display_mode;
52 	EAutomaticActionPolicy close_on_reply_policy;
53 
54 	GtkWidget *main_menu;
55 	GtkWidget *main_toolbar;
56 	GtkWidget *message_list;
57 	GtkWidget *preview_pane;
58 	GtkWidget *statusbar;
59 
60 	EAlert *close_on_reply_alert;
61 	gulong close_on_reply_response_handler_id;
62 
63 	guint show_deleted : 1;
64 	guint show_junk : 1;
65 	guint close_on_delete_or_junk : 1;
66 };
67 
68 enum {
69 	PROP_0,
70 	PROP_BACKEND,
71 	PROP_CLOSE_ON_REPLY_POLICY,
72 	PROP_DISPLAY_MODE,
73 	PROP_FOCUS_TRACKER,
74 	PROP_FORWARD_STYLE,
75 	PROP_GROUP_BY_THREADS,
76 	PROP_REPLY_STYLE,
77 	PROP_MARK_SEEN_ALWAYS,
78 	PROP_SHOW_DELETED,
79 	PROP_SHOW_JUNK,
80 	PROP_UI_MANAGER,
81 	PROP_DELETE_SELECTS_PREVIOUS,
82 	PROP_CLOSE_ON_DELETE_OR_JUNK
83 };
84 
85 /* This is too trivial to put in a file.
86  * It gets merged with the EMailReader UI. */
87 static const gchar *ui =
88 "<ui>"
89 "  <menubar name='main-menu'>"
90 "    <menu action='file-menu'>"
91 "      <placeholder name='file-actions'/>"
92 "      <placeholder name='print-actions'/>"
93 "      <separator/>"
94 "      <menuitem action='close'/>"
95 "    </menu>"
96 "    <menu action='edit-menu'>"
97 "      <placeholder name='selection-actions'>"
98 "        <menuitem action='cut-clipboard'/>"
99 "        <menuitem action='copy-clipboard'/>"
100 "        <menuitem action='paste-clipboard'/>"
101 "        <separator/>"
102 "        <menuitem action='select-all'/>"
103 "      </placeholder>"
104 "    </menu>"
105 "  </menubar>"
106 "</ui>";
107 
108 static void	e_mail_browser_reader_init
109 					(EMailReaderInterface *iface);
110 
G_DEFINE_TYPE_WITH_CODE(EMailBrowser,e_mail_browser,GTK_TYPE_WINDOW,G_IMPLEMENT_INTERFACE (E_TYPE_MAIL_READER,e_mail_browser_reader_init)G_IMPLEMENT_INTERFACE (E_TYPE_EXTENSIBLE,NULL))111 G_DEFINE_TYPE_WITH_CODE (
112 	EMailBrowser,
113 	e_mail_browser,
114 	GTK_TYPE_WINDOW,
115 	G_IMPLEMENT_INTERFACE (
116 		E_TYPE_MAIL_READER, e_mail_browser_reader_init)
117 	G_IMPLEMENT_INTERFACE (
118 		E_TYPE_EXTENSIBLE, NULL))
119 
120 static void
121 action_close_cb (GtkAction *action,
122                  EMailBrowser *browser)
123 {
124 	e_mail_browser_close (browser);
125 }
126 
127 static void
action_search_web_cb(GtkAction * action,EMailReader * reader)128 action_search_web_cb (GtkAction *action,
129 		      EMailReader *reader)
130 {
131 	EMailDisplay *display;
132 	GtkAction *wv_action;
133 
134 	display = e_mail_reader_get_mail_display (reader);
135 	wv_action = e_web_view_get_action (E_WEB_VIEW (display), "search-web");
136 
137 	gtk_action_activate (wv_action);
138 }
139 
140 static void
action_mail_smart_backward_cb(GtkAction * action,EMailReader * reader)141 action_mail_smart_backward_cb (GtkAction *action,
142 			       EMailReader *reader)
143 {
144 	EMailDisplay *mail_display;
145 
146 	mail_display = e_mail_reader_get_mail_display (reader);
147 
148 	e_mail_display_process_magic_spacebar (mail_display, FALSE);
149 }
150 
151 static void
action_mail_smart_forward_cb(GtkAction * action,EMailReader * reader)152 action_mail_smart_forward_cb (GtkAction *action,
153 			      EMailReader *reader)
154 {
155 	EMailDisplay *mail_display;
156 
157 	mail_display = e_mail_reader_get_mail_display (reader);
158 
159 	e_mail_display_process_magic_spacebar (mail_display, TRUE);
160 }
161 
162 static GtkActionEntry mail_browser_entries[] = {
163 
164 	{ "close",
165 	  "window-close",
166 	  N_("_Close"),
167 	  "<Control>w",
168 	  N_("Close this window"),
169 	  G_CALLBACK (action_close_cb) },
170 
171 	{ "copy-clipboard",
172 	  "edit-copy",
173 	  N_("_Copy"),
174 	  "<Control>c",
175 	  N_("Copy the selection"),
176 	  NULL },  /* Handled by EFocusTracker */
177 
178 	{ "cut-clipboard",
179 	  "edit-cut",
180 	  N_("Cu_t"),
181 	  "<Control>x",
182 	  N_("Cut the selection"),
183 	  NULL },  /* Handled by EFocusTracker */
184 
185 	{ "paste-clipboard",
186 	  "edit-paste",
187 	  N_("_Paste"),
188 	  "<Control>v",
189 	  N_("Paste the clipboard"),
190 	  NULL },  /* Handled by EFocusTracker */
191 
192 	{ "select-all",
193 	  "edit-select-all",
194 	  N_("Select _All"),
195 	  NULL,
196 	  N_("Select all text"),
197 	  NULL },  /* Handled by EFocusTracker */
198 
199 	{ "search-web",
200 	  NULL,
201 	  N_("Search _Web…"),
202 	  NULL,
203 	  N_("Search the Web with the selected text"),
204 	  G_CALLBACK (action_search_web_cb) },
205 
206 	/*** Menus ***/
207 
208 	{ "file-menu",
209 	  NULL,
210 	  N_("_File"),
211 	  NULL,
212 	  NULL,
213 	  NULL },
214 
215 	{ "edit-menu",
216 	  NULL,
217 	  N_("_Edit"),
218 	  NULL,
219 	  NULL,
220 	  NULL },
221 
222 	{ "view-menu",
223 	  NULL,
224 	  N_("_View"),
225 	  NULL,
226 	  NULL,
227 	  NULL }
228 };
229 
230 static GtkActionEntry mail_entries[] = {
231 
232 	{ "mail-smart-backward",
233 	  NULL,
234 	  NULL,
235 	  NULL,
236 	  NULL,
237 	  G_CALLBACK (action_mail_smart_backward_cb) },
238 
239 	{ "mail-smart-forward",
240 	  NULL,
241 	  NULL,
242 	  NULL,
243 	  NULL,
244 	  G_CALLBACK (action_mail_smart_forward_cb) },
245 };
246 
247 static EPopupActionEntry mail_browser_popup_entries[] = {
248 
249 	{ "popup-copy-clipboard",
250 	  NULL,
251 	  "copy-clipboard" },
252 
253 	{ "popup-search-web",
254 	  NULL,
255 	  "search-web" }
256 };
257 
258 static void
mail_browser_menu_item_select_cb(EMailBrowser * browser,GtkWidget * widget)259 mail_browser_menu_item_select_cb (EMailBrowser *browser,
260                                   GtkWidget *widget)
261 {
262 	GtkAction *action;
263 	GtkActivatable *activatable;
264 	GtkStatusbar *statusbar;
265 	const gchar *tooltip;
266 	guint context_id;
267 	gpointer data;
268 
269 	activatable = GTK_ACTIVATABLE (widget);
270 	action = gtk_activatable_get_related_action (activatable);
271 	tooltip = gtk_action_get_tooltip (action);
272 
273 	data = g_object_get_data (G_OBJECT (widget), "context-id");
274 	context_id = GPOINTER_TO_UINT (data);
275 
276 	if (tooltip == NULL)
277 		return;
278 
279 	statusbar = GTK_STATUSBAR (browser->priv->statusbar);
280 	gtk_statusbar_push (statusbar, context_id, tooltip);
281 }
282 
283 static void
mail_browser_menu_item_deselect_cb(EMailBrowser * browser,GtkWidget * menu_item)284 mail_browser_menu_item_deselect_cb (EMailBrowser *browser,
285                                     GtkWidget *menu_item)
286 {
287 	GtkStatusbar *statusbar;
288 	guint context_id;
289 	gpointer data;
290 
291 	data = g_object_get_data (G_OBJECT (menu_item), "context-id");
292 	context_id = GPOINTER_TO_UINT (data);
293 
294 	statusbar = GTK_STATUSBAR (browser->priv->statusbar);
295 	gtk_statusbar_pop (statusbar, context_id);
296 }
297 
298 static void
mail_browser_connect_proxy_cb(EMailBrowser * browser,GtkAction * action,GtkWidget * proxy)299 mail_browser_connect_proxy_cb (EMailBrowser *browser,
300                                GtkAction *action,
301                                GtkWidget *proxy)
302 {
303 	GtkStatusbar *statusbar;
304 	guint context_id;
305 
306 	if (!GTK_IS_MENU_ITEM (proxy))
307 		return;
308 
309 	statusbar = GTK_STATUSBAR (browser->priv->statusbar);
310 	context_id = gtk_statusbar_get_context_id (statusbar, G_STRFUNC);
311 
312 	g_object_set_data (
313 		G_OBJECT (proxy), "context-id",
314 		GUINT_TO_POINTER (context_id));
315 
316 	g_signal_connect_swapped (
317 		proxy, "select",
318 		G_CALLBACK (mail_browser_menu_item_select_cb), browser);
319 
320 	g_signal_connect_swapped (
321 		proxy, "deselect",
322 		G_CALLBACK (mail_browser_menu_item_deselect_cb), browser);
323 }
324 
325 static void
mail_browser_message_selected_cb(EMailBrowser * browser,const gchar * uid)326 mail_browser_message_selected_cb (EMailBrowser *browser,
327                                   const gchar *uid)
328 {
329 	CamelMessageInfo *info;
330 	CamelFolder *folder;
331 	EMailReader *reader;
332 	guint32 state;
333 
334 	reader = E_MAIL_READER (browser);
335 	state = e_mail_reader_check_state (reader);
336 	e_mail_reader_update_actions (reader, state);
337 
338 	if (uid == NULL)
339 		return;
340 
341 	folder = e_mail_reader_ref_folder (reader);
342 
343 	info = camel_folder_get_message_info (folder, uid);
344 
345 	if (info != NULL) {
346 		EMailDisplay *display;
347 		const gchar *title;
348 
349 		display = e_mail_reader_get_mail_display (reader);
350 
351 		title = camel_message_info_get_subject (info);
352 		if (title == NULL || *title == '\0')
353 			title = _("(No Subject)");
354 
355 		gtk_window_set_title (GTK_WINDOW (browser), title);
356 
357 		if (gtk_widget_get_mapped (GTK_WIDGET (browser)))
358 			gtk_widget_grab_focus (GTK_WIDGET (display));
359 
360 		if (e_mail_reader_utils_get_mark_seen_setting (reader, NULL))
361 			camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
362 
363 		g_clear_object (&info);
364 	}
365 
366 	g_clear_object (&folder);
367 }
368 
369 static gboolean
close_on_idle_cb(gpointer browser)370 close_on_idle_cb (gpointer browser)
371 {
372 	e_mail_browser_close (browser);
373 	return FALSE;
374 }
375 
376 static void
mail_browser_message_list_built_cb(EMailBrowser * browser,MessageList * message_list)377 mail_browser_message_list_built_cb (EMailBrowser *browser,
378                                     MessageList *message_list)
379 {
380 	g_return_if_fail (E_IS_MAIL_BROWSER (browser));
381 	g_return_if_fail (IS_MESSAGE_LIST (message_list));
382 
383 	if (message_list_count (message_list) == 0)
384 		/* Prioritize ahead of GTK+ redraws. */
385 		g_idle_add_full (
386 			G_PRIORITY_HIGH_IDLE,
387 			close_on_idle_cb, browser, NULL);
388 }
389 
390 static gboolean
mail_browser_popup_event_cb(EMailBrowser * browser,const gchar * uri,GdkEvent * event)391 mail_browser_popup_event_cb (EMailBrowser *browser,
392                              const gchar *uri,
393                              GdkEvent *event)
394 {
395 	EMailReader *reader;
396 	EWebView *web_view;
397 	GtkMenu *menu;
398 	guint32 state;
399 
400 	if (uri != NULL)
401 		return FALSE;
402 
403 	reader = E_MAIL_READER (browser);
404 	web_view = E_WEB_VIEW (e_mail_reader_get_mail_display (reader));
405 
406 	if (e_web_view_get_cursor_image_src (web_view) != NULL)
407 		return FALSE;
408 
409 	menu = e_mail_reader_get_popup_menu (reader);
410 
411 	state = e_mail_reader_check_state (reader);
412 	e_mail_reader_update_actions (reader, state);
413 
414 	gtk_menu_popup_at_pointer (menu, event);
415 
416 	return TRUE;
417 }
418 
419 static void
mail_browser_status_message_cb(EMailBrowser * browser,const gchar * status_message)420 mail_browser_status_message_cb (EMailBrowser *browser,
421                                 const gchar *status_message)
422 {
423 	GtkStatusbar *statusbar;
424 	guint context_id;
425 
426 	statusbar = GTK_STATUSBAR (browser->priv->statusbar);
427 	context_id = gtk_statusbar_get_context_id (statusbar, G_STRFUNC);
428 
429 	/* Always pop first.  This prevents messages from piling up. */
430 	gtk_statusbar_pop (statusbar, context_id);
431 
432 	if (status_message != NULL && *status_message != '\0')
433 		gtk_statusbar_push (statusbar, context_id, status_message);
434 }
435 
436 static void
mail_browser_close_on_reply_response_cb(EAlert * alert,gint response_id,EMailBrowser * browser)437 mail_browser_close_on_reply_response_cb (EAlert *alert,
438                                          gint response_id,
439                                          EMailBrowser *browser)
440 {
441 	/* Disconnect the signal handler, but leave the EAlert
442 	 * itself in place so we know it's already been presented. */
443 	g_signal_handler_disconnect (
444 		browser->priv->close_on_reply_alert,
445 		browser->priv->close_on_reply_response_handler_id);
446 	browser->priv->close_on_reply_response_handler_id = 0;
447 
448 	if (response_id == GTK_RESPONSE_YES) {
449 		e_mail_browser_set_close_on_reply_policy (
450 			browser, E_AUTOMATIC_ACTION_POLICY_ALWAYS);
451 		e_mail_browser_close (browser);
452 	}
453 
454 	if (response_id == GTK_RESPONSE_NO) {
455 		e_mail_browser_set_close_on_reply_policy (
456 			browser, E_AUTOMATIC_ACTION_POLICY_NEVER);
457 	}
458 }
459 
460 static gboolean
mail_browser_key_press_event_cb(GtkWindow * mail_browser,GdkEventKey * event)461 mail_browser_key_press_event_cb (GtkWindow *mail_browser,
462 				 GdkEventKey *event)
463 {
464 	GtkWidget *focused;
465 	EMailDisplay *mail_display;
466 
467 	mail_display = e_mail_reader_get_mail_display (E_MAIL_READER (mail_browser));
468 
469 	if (!event || (event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)) != 0 ||
470 	    event->keyval == GDK_KEY_Tab ||
471 	    event->keyval == GDK_KEY_Return ||
472 	    event->keyval == GDK_KEY_KP_Tab ||
473 	    event->keyval == GDK_KEY_KP_Enter)
474 		return event && e_mail_display_need_key_event (mail_display, event);
475 
476 	focused = gtk_window_get_focus (mail_browser);
477 
478 	if (focused && (GTK_IS_ENTRY (focused) || GTK_IS_EDITABLE (focused) ||
479 	    (GTK_IS_TREE_VIEW (focused) && gtk_tree_view_get_search_column (GTK_TREE_VIEW (focused)) >= 0))) {
480 		gtk_widget_event (focused, (GdkEvent *) event);
481 		return event->keyval != GDK_KEY_Escape;
482 	}
483 
484 	if (e_web_view_get_need_input (E_WEB_VIEW (mail_display)) &&
485 	    gtk_widget_has_focus (GTK_WIDGET (mail_display))) {
486 		gtk_widget_event (GTK_WIDGET (mail_display), (GdkEvent *) event);
487 		return TRUE;
488 	}
489 
490 	if (e_mail_display_need_key_event (mail_display, event))
491 		return TRUE;
492 
493 	if (event->keyval == GDK_KEY_Escape) {
494 		e_mail_browser_close (E_MAIL_BROWSER (mail_browser));
495 		return TRUE;
496 	}
497 
498 	return FALSE;
499 }
500 
501 static void
mail_browser_set_backend(EMailBrowser * browser,EMailBackend * backend)502 mail_browser_set_backend (EMailBrowser *browser,
503                           EMailBackend *backend)
504 {
505 	g_return_if_fail (E_IS_MAIL_BACKEND (backend));
506 	g_return_if_fail (browser->priv->backend == NULL);
507 
508 	browser->priv->backend = g_object_ref (backend);
509 }
510 
511 static void
mail_browser_set_display_mode(EMailBrowser * browser,EMailFormatterMode display_mode)512 mail_browser_set_display_mode (EMailBrowser *browser,
513                                EMailFormatterMode display_mode)
514 {
515 	browser->priv->display_mode = display_mode;
516 }
517 
518 static void
mail_browser_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)519 mail_browser_set_property (GObject *object,
520                            guint property_id,
521                            const GValue *value,
522                            GParamSpec *pspec)
523 {
524 	switch (property_id) {
525 		case PROP_BACKEND:
526 			mail_browser_set_backend (
527 				E_MAIL_BROWSER (object),
528 				g_value_get_object (value));
529 			return;
530 
531 		case PROP_CLOSE_ON_REPLY_POLICY:
532 			e_mail_browser_set_close_on_reply_policy (
533 				E_MAIL_BROWSER (object),
534 				g_value_get_enum (value));
535 			return;
536 
537 		case PROP_DISPLAY_MODE:
538 			mail_browser_set_display_mode (
539 				E_MAIL_BROWSER (object),
540 				g_value_get_enum (value));
541 			return;
542 
543 		case PROP_FORWARD_STYLE:
544 			e_mail_reader_set_forward_style (
545 				E_MAIL_READER (object),
546 				g_value_get_enum (value));
547 			return;
548 
549 		case PROP_GROUP_BY_THREADS:
550 			e_mail_reader_set_group_by_threads (
551 				E_MAIL_READER (object),
552 				g_value_get_boolean (value));
553 			return;
554 
555 		case PROP_REPLY_STYLE:
556 			e_mail_reader_set_reply_style (
557 				E_MAIL_READER (object),
558 				g_value_get_enum (value));
559 			return;
560 
561 		case PROP_SHOW_DELETED:
562 			e_mail_browser_set_show_deleted (
563 				E_MAIL_BROWSER (object),
564 				g_value_get_boolean (value));
565 			return;
566 
567 		case PROP_SHOW_JUNK:
568 			e_mail_browser_set_show_junk (
569 				E_MAIL_BROWSER (object),
570 				g_value_get_boolean (value));
571 			return;
572 
573 		case PROP_MARK_SEEN_ALWAYS:
574 			e_mail_reader_set_mark_seen_always (
575 				E_MAIL_READER (object),
576 				g_value_get_boolean (value));
577 			return;
578 
579 		case PROP_DELETE_SELECTS_PREVIOUS:
580 			e_mail_reader_set_delete_selects_previous (
581 				E_MAIL_READER (object),
582 				g_value_get_boolean (value));
583 			return;
584 
585 		case PROP_CLOSE_ON_DELETE_OR_JUNK:
586 			e_mail_browser_set_close_on_delete_or_junk (
587 				E_MAIL_BROWSER (object),
588 				g_value_get_boolean (value));
589 			return;
590 	}
591 
592 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
593 }
594 
595 static void
mail_browser_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)596 mail_browser_get_property (GObject *object,
597                            guint property_id,
598                            GValue *value,
599                            GParamSpec *pspec)
600 {
601 	switch (property_id) {
602 		case PROP_BACKEND:
603 			g_value_set_object (
604 				value,
605 				e_mail_reader_get_backend (
606 				E_MAIL_READER (object)));
607 			return;
608 
609 		case PROP_CLOSE_ON_REPLY_POLICY:
610 			g_value_set_enum (
611 				value,
612 				e_mail_browser_get_close_on_reply_policy (
613 				E_MAIL_BROWSER (object)));
614 			return;
615 
616 		case PROP_DISPLAY_MODE:
617 			g_value_set_enum (
618 				value,
619 				e_mail_browser_get_display_mode (
620 				E_MAIL_BROWSER (object)));
621 			return;
622 
623 		case PROP_FOCUS_TRACKER:
624 			g_value_set_object (
625 				value,
626 				e_mail_browser_get_focus_tracker (
627 				E_MAIL_BROWSER (object)));
628 			return;
629 
630 		case PROP_FORWARD_STYLE:
631 			g_value_set_enum (
632 				value,
633 				e_mail_reader_get_forward_style (
634 				E_MAIL_READER (object)));
635 			return;
636 
637 		case PROP_GROUP_BY_THREADS:
638 			g_value_set_boolean (
639 				value,
640 				e_mail_reader_get_group_by_threads (
641 				E_MAIL_READER (object)));
642 			return;
643 
644 		case PROP_REPLY_STYLE:
645 			g_value_set_enum (
646 				value,
647 				e_mail_reader_get_reply_style (
648 				E_MAIL_READER (object)));
649 			return;
650 
651 		case PROP_SHOW_DELETED:
652 			g_value_set_boolean (
653 				value,
654 				e_mail_browser_get_show_deleted (
655 				E_MAIL_BROWSER (object)));
656 			return;
657 
658 		case PROP_SHOW_JUNK:
659 			g_value_set_boolean (
660 				value,
661 				e_mail_browser_get_show_junk (
662 				E_MAIL_BROWSER (object)));
663 			return;
664 
665 		case PROP_UI_MANAGER:
666 			g_value_set_object (
667 				value,
668 				e_mail_browser_get_ui_manager (
669 				E_MAIL_BROWSER (object)));
670 			return;
671 
672 		case PROP_MARK_SEEN_ALWAYS:
673 			g_value_set_boolean (
674 				value,
675 				e_mail_reader_get_mark_seen_always (
676 				E_MAIL_READER (object)));
677 			return;
678 
679 		case PROP_DELETE_SELECTS_PREVIOUS:
680 			g_value_set_boolean (
681 				value,
682 				e_mail_reader_get_delete_selects_previous (
683 				E_MAIL_READER (object)));
684 			return;
685 
686 		case PROP_CLOSE_ON_DELETE_OR_JUNK:
687 			g_value_set_boolean (
688 				value,
689 				e_mail_browser_get_close_on_delete_or_junk (
690 				E_MAIL_BROWSER (object)));
691 			return;
692 	}
693 
694 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
695 }
696 
697 static void
mail_browser_dispose(GObject * object)698 mail_browser_dispose (GObject *object)
699 {
700 	EMailBrowserPrivate *priv;
701 
702 	priv = E_MAIL_BROWSER_GET_PRIVATE (object);
703 
704 	e_mail_reader_dispose (E_MAIL_READER (object));
705 
706 	if (priv->close_on_reply_response_handler_id > 0) {
707 		g_signal_handler_disconnect (
708 			priv->close_on_reply_alert,
709 			priv->close_on_reply_response_handler_id);
710 		priv->close_on_reply_response_handler_id = 0;
711 	}
712 
713 	g_clear_object (&priv->backend);
714 	g_clear_object (&priv->ui_manager);
715 	g_clear_object (&priv->focus_tracker);
716 	g_clear_object (&priv->main_menu);
717 	g_clear_object (&priv->main_toolbar);
718 	g_clear_object (&priv->preview_pane);
719 	g_clear_object (&priv->statusbar);
720 	g_clear_object (&priv->close_on_reply_alert);
721 
722 	if (priv->message_list != NULL) {
723 		/* This will cancel a regen operation. */
724 		gtk_widget_destroy (priv->message_list);
725 		g_clear_object (&priv->message_list);
726 	}
727 
728 	/* Chain up to parent's dispose() method. */
729 	G_OBJECT_CLASS (e_mail_browser_parent_class)->dispose (object);
730 }
731 
732 static void
mail_browser_constructed(GObject * object)733 mail_browser_constructed (GObject *object)
734 {
735 	EMailBrowser *browser;
736 	EMailReader *reader;
737 	EMailBackend *backend;
738 	EMailSession *session;
739 	EShellBackend *shell_backend;
740 	EShell *shell;
741 	EFocusTracker *focus_tracker;
742 	EAttachmentStore *attachment_store;
743 	GtkAccelGroup *accel_group;
744 	GtkActionGroup *action_group;
745 	GtkAction *action, *mail_action;
746 	GtkUIManager *ui_manager;
747 	GtkWidget *container;
748 	GtkWidget *display;
749 	GtkWidget *widget;
750 	const gchar *domain;
751 	const gchar *id;
752 	guint merge_id;
753 
754 	/* Chain up to parent's constructed() method. */
755 	G_OBJECT_CLASS (e_mail_browser_parent_class)->constructed (object);
756 
757 	browser = E_MAIL_BROWSER (object);
758 	reader = E_MAIL_READER (object);
759 	backend = e_mail_reader_get_backend (reader);
760 	session = e_mail_backend_get_session (backend);
761 
762 	shell_backend = E_SHELL_BACKEND (backend);
763 	shell = e_shell_backend_get_shell (shell_backend);
764 
765 	ui_manager = gtk_ui_manager_new ();
766 
767 	browser->priv->ui_manager = ui_manager;
768 	domain = GETTEXT_PACKAGE;
769 
770 	gtk_application_add_window (
771 		GTK_APPLICATION (shell), GTK_WINDOW (object));
772 
773 	/* The message list is a widget, but it is not shown in the browser.
774 	 * Unfortunately, the widget is inseparable from its model, and the
775 	 * model is all we need. */
776 	browser->priv->message_list = message_list_new (session);
777 	g_object_ref_sink (browser->priv->message_list);
778 
779 	g_signal_connect_swapped (
780 		browser->priv->message_list, "message-selected",
781 		G_CALLBACK (mail_browser_message_selected_cb), object);
782 
783 	g_signal_connect_swapped (
784 		browser->priv->message_list, "message-list-built",
785 		G_CALLBACK (mail_browser_message_list_built_cb), object);
786 
787 	display = e_mail_display_new (e_mail_backend_get_remote_content (backend));
788 
789 	e_mail_display_set_mode (
790 		E_MAIL_DISPLAY (display),
791 		browser->priv->display_mode);
792 
793 	g_signal_connect_swapped (
794 		display, "popup-event",
795 		G_CALLBACK (mail_browser_popup_event_cb), object);
796 
797 	g_signal_connect_swapped (
798 		display, "status-message",
799 		G_CALLBACK (mail_browser_status_message_cb), object);
800 
801 	widget = e_preview_pane_new (E_WEB_VIEW (display));
802 	browser->priv->preview_pane = g_object_ref (widget);
803 	gtk_widget_show (widget);
804 
805 	action_group = gtk_action_group_new ("mail");
806 	gtk_action_group_set_translation_domain (action_group, domain);
807 	gtk_action_group_add_actions (
808 		action_group, mail_entries,
809 		G_N_ELEMENTS (mail_entries), object);
810 	gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
811 
812 	action_group = gtk_action_group_new (ACTION_GROUP_STANDARD);
813 	gtk_action_group_set_translation_domain (action_group, domain);
814 	gtk_action_group_add_actions (
815 		action_group, mail_browser_entries,
816 		G_N_ELEMENTS (mail_browser_entries), object);
817 	e_action_group_add_popup_actions (
818 		action_group, mail_browser_popup_entries,
819 		G_N_ELEMENTS (mail_browser_popup_entries));
820 	gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
821 
822 	mail_action = e_web_view_get_action (E_WEB_VIEW (display), "search-web");
823 	action = gtk_action_group_get_action (action_group, "search-web");
824 
825 	e_binding_bind_property (
826 		mail_action, "sensitive",
827 		action, "sensitive",
828 		G_BINDING_SYNC_CREATE);
829 
830 	/* For easy access.  Takes ownership of the reference. */
831 	g_object_set_data_full (
832 		object, ACTION_GROUP_STANDARD,
833 		action_group, (GDestroyNotify) g_object_unref);
834 
835 	action_group = gtk_action_group_new (ACTION_GROUP_SEARCH_FOLDERS);
836 	gtk_action_group_set_translation_domain (action_group, domain);
837 	gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
838 
839 	/* For easy access.  Takes ownership of the reference. */
840 	g_object_set_data_full (
841 		object, ACTION_GROUP_SEARCH_FOLDERS,
842 		action_group, (GDestroyNotify) g_object_unref);
843 
844 	action_group = gtk_action_group_new (ACTION_GROUP_LABELS);
845 	gtk_action_group_set_translation_domain (action_group, domain);
846 	gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
847 
848 	/* For easy access.  Takes ownership of the reference. */
849 	g_object_set_data_full (
850 		object, ACTION_GROUP_LABELS,
851 		action_group, (GDestroyNotify) g_object_unref);
852 
853 	e_binding_bind_property (
854 		display, "need-input",
855 		action_group, "sensitive",
856 		G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
857 
858 	e_mail_reader_init (reader, TRUE, TRUE);
859 
860 	e_load_ui_manager_definition (ui_manager, E_MAIL_READER_UI_DEFINITION);
861 	gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, NULL);
862 
863 	merge_id = gtk_ui_manager_new_merge_id (ui_manager);
864 	e_mail_reader_create_charset_menu (reader, ui_manager, merge_id);
865 
866 	accel_group = gtk_ui_manager_get_accel_group (ui_manager);
867 	gtk_window_add_accel_group (GTK_WINDOW (object), accel_group);
868 
869 	g_signal_connect_swapped (
870 		ui_manager, "connect-proxy",
871 		G_CALLBACK (mail_browser_connect_proxy_cb), object);
872 
873 	/* Configure an EFocusTracker to manage selection actions. */
874 
875 	focus_tracker = e_focus_tracker_new (GTK_WINDOW (object));
876 	action = e_mail_reader_get_action (reader, "cut-clipboard");
877 	e_focus_tracker_set_cut_clipboard_action (focus_tracker, action);
878 	action = e_mail_reader_get_action (reader, "copy-clipboard");
879 	e_focus_tracker_set_copy_clipboard_action (focus_tracker, action);
880 	action = e_mail_reader_get_action (reader, "paste-clipboard");
881 	e_focus_tracker_set_paste_clipboard_action (focus_tracker, action);
882 	action = e_mail_reader_get_action (reader, "select-all");
883 	e_focus_tracker_set_select_all_action (focus_tracker, action);
884 	browser->priv->focus_tracker = focus_tracker;
885 
886 	/* Construct window widgets. */
887 
888 	widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
889 	gtk_container_add (GTK_CONTAINER (object), widget);
890 	gtk_widget_show (widget);
891 
892 	container = widget;
893 
894 	widget = gtk_statusbar_new ();
895 	gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0);
896 	browser->priv->statusbar = g_object_ref (widget);
897 	gtk_widget_show (widget);
898 
899 	widget = gtk_ui_manager_get_widget (ui_manager, "/main-menu");
900 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
901 	browser->priv->main_menu = g_object_ref (widget);
902 	gtk_widget_show (widget);
903 
904 	widget = gtk_ui_manager_get_widget (ui_manager, "/main-toolbar");
905 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
906 	browser->priv->main_toolbar = g_object_ref (widget);
907 	gtk_widget_show (widget);
908 
909 	gtk_style_context_add_class (
910 		gtk_widget_get_style_context (widget),
911 		GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
912 
913 	gtk_box_pack_start (
914 		GTK_BOX (container),
915 		browser->priv->preview_pane,
916 		TRUE, TRUE, 0);
917 
918 	attachment_store = e_mail_display_get_attachment_store (E_MAIL_DISPLAY (display));
919 	widget = GTK_WIDGET (e_mail_display_get_attachment_view (E_MAIL_DISPLAY (display)));
920 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
921 	gtk_widget_show (widget);
922 
923 	e_binding_bind_property_full (
924 		attachment_store, "num-attachments",
925 		widget, "visible",
926 		G_BINDING_SYNC_CREATE,
927 		e_attachment_store_transform_num_attachments_to_visible_boolean,
928 		NULL, NULL, NULL);
929 
930 	id = "org.gnome.evolution.mail.browser";
931 	e_plugin_ui_register_manager (ui_manager, id, object);
932 	e_plugin_ui_enable_manager (ui_manager, id);
933 
934 	action = e_mail_reader_get_action (reader, "mail-label-none");
935 	e_binding_bind_property (
936 		display, "need-input",
937 		action, "sensitive",
938 		G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
939 
940 	g_signal_connect (
941 		browser, "key-press-event",
942 		G_CALLBACK (mail_browser_key_press_event_cb), NULL);
943 
944 	e_extensible_load_extensions (E_EXTENSIBLE (object));
945 }
946 
947 static GtkActionGroup *
mail_browser_get_action_group(EMailReader * reader,EMailReaderActionGroup group)948 mail_browser_get_action_group (EMailReader *reader,
949                                EMailReaderActionGroup group)
950 {
951 	const gchar *group_name;
952 
953 	switch (group) {
954 		case E_MAIL_READER_ACTION_GROUP_STANDARD:
955 			group_name = ACTION_GROUP_STANDARD;
956 			break;
957 		case E_MAIL_READER_ACTION_GROUP_SEARCH_FOLDERS:
958 			group_name = ACTION_GROUP_SEARCH_FOLDERS;
959 			break;
960 		case E_MAIL_READER_ACTION_GROUP_LABELS:
961 			group_name = ACTION_GROUP_LABELS;
962 			break;
963 		default:
964 			g_return_val_if_reached (NULL);
965 	}
966 
967 	return g_object_get_data (G_OBJECT (reader), group_name);
968 }
969 
970 static EMailBackend *
mail_browser_get_backend(EMailReader * reader)971 mail_browser_get_backend (EMailReader *reader)
972 {
973 	EMailBrowser *browser;
974 
975 	browser = E_MAIL_BROWSER (reader);
976 
977 	return browser->priv->backend;
978 }
979 
980 static gboolean
mail_browser_get_hide_deleted(EMailReader * reader)981 mail_browser_get_hide_deleted (EMailReader *reader)
982 {
983 	EMailBrowser *browser;
984 
985 	browser = E_MAIL_BROWSER (reader);
986 
987 	return !e_mail_browser_get_show_deleted (browser);
988 }
989 
990 static EMailDisplay *
mail_browser_get_mail_display(EMailReader * reader)991 mail_browser_get_mail_display (EMailReader *reader)
992 {
993 	EPreviewPane *preview_pane;
994 	EWebView *web_view;
995 
996 	preview_pane = e_mail_reader_get_preview_pane (reader);
997 	if (!preview_pane)
998 		return NULL;
999 
1000 	web_view = e_preview_pane_get_web_view (preview_pane);
1001 
1002 	return E_MAIL_DISPLAY (web_view);
1003 }
1004 
1005 static GtkWidget *
mail_browser_get_message_list(EMailReader * reader)1006 mail_browser_get_message_list (EMailReader *reader)
1007 {
1008 	EMailBrowserPrivate *priv;
1009 
1010 	priv = E_MAIL_BROWSER_GET_PRIVATE (reader);
1011 
1012 	return priv->message_list;
1013 }
1014 
1015 static GtkMenu *
mail_browser_get_popup_menu(EMailReader * reader)1016 mail_browser_get_popup_menu (EMailReader *reader)
1017 {
1018 	EMailBrowser *browser;
1019 	GtkUIManager *ui_manager;
1020 	GtkWidget *widget;
1021 
1022 	browser = E_MAIL_BROWSER (reader);
1023 	ui_manager = e_mail_browser_get_ui_manager (browser);
1024 	if (!ui_manager)
1025 		return NULL;
1026 
1027 	widget = gtk_ui_manager_get_widget (ui_manager, "/mail-preview-popup");
1028 
1029 	return GTK_MENU (widget);
1030 }
1031 
1032 static EPreviewPane *
mail_browser_get_preview_pane(EMailReader * reader)1033 mail_browser_get_preview_pane (EMailReader *reader)
1034 {
1035 	EMailBrowserPrivate *priv;
1036 
1037 	priv = E_MAIL_BROWSER_GET_PRIVATE (reader);
1038 
1039 	if (!priv->preview_pane)
1040 		return NULL;
1041 
1042 	return E_PREVIEW_PANE (priv->preview_pane);
1043 }
1044 
1045 static GtkWindow *
mail_browser_get_window(EMailReader * reader)1046 mail_browser_get_window (EMailReader *reader)
1047 {
1048 	return GTK_WINDOW (reader);
1049 }
1050 
1051 static void
mail_browser_set_message(EMailReader * reader,const gchar * uid)1052 mail_browser_set_message (EMailReader *reader,
1053                           const gchar *uid)
1054 {
1055 	EMailReaderInterface *iface;
1056 	EMailBrowser *browser;
1057 	CamelMessageInfo *info;
1058 	CamelFolder *folder;
1059 
1060 	browser = E_MAIL_BROWSER (reader);
1061 
1062 	/* Chain up to parent's set_message() method. */
1063 	iface = g_type_default_interface_peek (E_TYPE_MAIL_READER);
1064 	iface->set_message (reader, uid);
1065 
1066 	if (uid == NULL) {
1067 		e_mail_browser_close (browser);
1068 		return;
1069 	}
1070 
1071 	folder = e_mail_reader_ref_folder (reader);
1072 
1073 	info = camel_folder_get_message_info (folder, uid);
1074 
1075 	if (info != NULL) {
1076 		gtk_window_set_title (
1077 			GTK_WINDOW (reader),
1078 			camel_message_info_get_subject (info));
1079 		g_clear_object (&info);
1080 	}
1081 
1082 	g_clear_object (&folder);
1083 }
1084 
1085 static void
mail_browser_composer_created(EMailReader * reader,EMsgComposer * composer,CamelMimeMessage * message)1086 mail_browser_composer_created (EMailReader *reader,
1087                                EMsgComposer *composer,
1088                                CamelMimeMessage *message)
1089 {
1090 	EMailBrowser *browser;
1091 	EAutomaticActionPolicy policy;
1092 
1093 	/* Do not prompt if there is no source message.  It means
1094 	 * the user wants to start a brand new message, presumably
1095 	 * unrelated to the message shown in the browser window. */
1096 	if (message == NULL)
1097 		return;
1098 
1099 	browser = E_MAIL_BROWSER (reader);
1100 	policy = e_mail_browser_get_close_on_reply_policy (browser);
1101 
1102 	switch (policy) {
1103 		case E_AUTOMATIC_ACTION_POLICY_ALWAYS:
1104 			e_mail_browser_close (browser);
1105 			break;
1106 
1107 		case E_AUTOMATIC_ACTION_POLICY_NEVER:
1108 			/* do nothing */
1109 			break;
1110 
1111 		case E_AUTOMATIC_ACTION_POLICY_ASK:
1112 			e_mail_browser_ask_close_on_reply (browser);
1113 			break;
1114 	}
1115 }
1116 
1117 static gboolean
mail_browser_close_on_delete_or_junk(EMailReader * reader)1118 mail_browser_close_on_delete_or_junk (EMailReader *reader)
1119 {
1120 	g_return_val_if_fail (E_IS_MAIL_BROWSER (reader), FALSE);
1121 
1122 	if (!e_mail_browser_get_close_on_delete_or_junk (E_MAIL_BROWSER (reader)))
1123 		return FALSE;
1124 
1125 	g_idle_add_full (
1126 		G_PRIORITY_HIGH_IDLE,
1127 		close_on_idle_cb, reader, NULL);
1128 
1129 	return TRUE;
1130 }
1131 
1132 static void
e_mail_browser_class_init(EMailBrowserClass * class)1133 e_mail_browser_class_init (EMailBrowserClass *class)
1134 {
1135 	GObjectClass *object_class;
1136 
1137 	g_type_class_add_private (class, sizeof (EMailBrowserPrivate));
1138 
1139 	object_class = G_OBJECT_CLASS (class);
1140 	object_class->set_property = mail_browser_set_property;
1141 	object_class->get_property = mail_browser_get_property;
1142 	object_class->dispose = mail_browser_dispose;
1143 	object_class->constructed = mail_browser_constructed;
1144 
1145 	g_object_class_install_property (
1146 		object_class,
1147 		PROP_BACKEND,
1148 		g_param_spec_object (
1149 			"backend",
1150 			"Mail Backend",
1151 			"The mail backend",
1152 			E_TYPE_MAIL_BACKEND,
1153 			G_PARAM_READWRITE |
1154 			G_PARAM_CONSTRUCT_ONLY |
1155 			G_PARAM_STATIC_STRINGS));
1156 
1157 	g_object_class_install_property (
1158 		object_class,
1159 		PROP_CLOSE_ON_REPLY_POLICY,
1160 		g_param_spec_enum (
1161 			"close-on-reply-policy",
1162 			"Close on Reply Policy",
1163 			"Policy for automatically closing the message "
1164 			"browser window when forwarding or replying to "
1165 			"the displayed message",
1166 			E_TYPE_AUTOMATIC_ACTION_POLICY,
1167 			E_AUTOMATIC_ACTION_POLICY_ASK,
1168 			G_PARAM_READWRITE |
1169 			G_PARAM_CONSTRUCT |
1170 			G_PARAM_STATIC_STRINGS));
1171 
1172 	g_object_class_install_property (
1173 		object_class,
1174 		PROP_DISPLAY_MODE,
1175 		g_param_spec_enum (
1176 			"display-mode",
1177 			"Display Mode",
1178 			NULL,
1179 			E_TYPE_MAIL_FORMATTER_MODE,
1180 			E_MAIL_FORMATTER_MODE_NORMAL,
1181 			G_PARAM_READWRITE |
1182 			G_PARAM_CONSTRUCT_ONLY |
1183 			G_PARAM_STATIC_STRINGS));
1184 
1185 	g_object_class_install_property (
1186 		object_class,
1187 		PROP_FOCUS_TRACKER,
1188 		g_param_spec_object (
1189 			"focus-tracker",
1190 			"Focus Tracker",
1191 			NULL,
1192 			E_TYPE_FOCUS_TRACKER,
1193 			G_PARAM_READABLE |
1194 			G_PARAM_STATIC_STRINGS));
1195 
1196 	/* Inherited from EMailReader */
1197 	g_object_class_override_property (
1198 		object_class,
1199 		PROP_FORWARD_STYLE,
1200 		"forward-style");
1201 
1202 	/* Inherited from EMailReader */
1203 	g_object_class_override_property (
1204 		object_class,
1205 		PROP_GROUP_BY_THREADS,
1206 		"group-by-threads");
1207 
1208 	/* Inherited from EMailReader */
1209 	g_object_class_override_property (
1210 		object_class,
1211 		PROP_REPLY_STYLE,
1212 		"reply-style");
1213 
1214 	/* Inherited from EMailReader */
1215 	g_object_class_override_property (
1216 		object_class,
1217 		PROP_MARK_SEEN_ALWAYS,
1218 		"mark-seen-always");
1219 
1220 	/* Inherited from EMailReader */
1221 	g_object_class_override_property (
1222 		object_class,
1223 		PROP_DELETE_SELECTS_PREVIOUS,
1224 		"delete-selects-previous");
1225 
1226 	g_object_class_install_property (
1227 		object_class,
1228 		PROP_SHOW_DELETED,
1229 		g_param_spec_boolean (
1230 			"show-deleted",
1231 			"Show Deleted",
1232 			"Show deleted messages",
1233 			FALSE,
1234 			G_PARAM_READWRITE |
1235 			G_PARAM_STATIC_STRINGS));
1236 
1237 	g_object_class_install_property (
1238 		object_class,
1239 		PROP_SHOW_JUNK,
1240 		g_param_spec_boolean (
1241 			"show-junk",
1242 			"Show Junk",
1243 			"Show junk messages",
1244 			FALSE,
1245 			G_PARAM_READWRITE |
1246 			G_PARAM_STATIC_STRINGS));
1247 
1248 	g_object_class_install_property (
1249 		object_class,
1250 		PROP_UI_MANAGER,
1251 		g_param_spec_object (
1252 			"ui-manager",
1253 			"UI Manager",
1254 			NULL,
1255 			GTK_TYPE_UI_MANAGER,
1256 			G_PARAM_READABLE |
1257 			G_PARAM_STATIC_STRINGS));
1258 
1259 	g_object_class_install_property (
1260 		object_class,
1261 		PROP_CLOSE_ON_DELETE_OR_JUNK,
1262 		g_param_spec_boolean (
1263 			"close-on-delete-or-junk",
1264 			"Close On Delete Or Junk",
1265 			"Close on message delete or when marked as Junk",
1266 			FALSE,
1267 			G_PARAM_CONSTRUCT |
1268 			G_PARAM_READWRITE |
1269 			G_PARAM_STATIC_STRINGS));
1270 }
1271 
1272 static void
e_mail_browser_reader_init(EMailReaderInterface * iface)1273 e_mail_browser_reader_init (EMailReaderInterface *iface)
1274 {
1275 	iface->get_action_group = mail_browser_get_action_group;
1276 	iface->get_backend = mail_browser_get_backend;
1277 	iface->get_mail_display = mail_browser_get_mail_display;
1278 	iface->get_hide_deleted = mail_browser_get_hide_deleted;
1279 	iface->get_message_list = mail_browser_get_message_list;
1280 	iface->get_popup_menu = mail_browser_get_popup_menu;
1281 	iface->get_preview_pane = mail_browser_get_preview_pane;
1282 	iface->get_window = mail_browser_get_window;
1283 	iface->set_message = mail_browser_set_message;
1284 	iface->composer_created = mail_browser_composer_created;
1285 	iface->close_on_delete_or_junk = mail_browser_close_on_delete_or_junk;
1286 }
1287 
1288 static void
e_mail_browser_init(EMailBrowser * browser)1289 e_mail_browser_init (EMailBrowser *browser)
1290 {
1291 	browser->priv = E_MAIL_BROWSER_GET_PRIVATE (browser);
1292 
1293 	gtk_window_set_title (GTK_WINDOW (browser), _("Evolution"));
1294 	gtk_window_set_default_size (GTK_WINDOW (browser), 600, 400);
1295 
1296 	e_restore_window (
1297 		GTK_WINDOW (browser),
1298 		"/org/gnome/evolution/mail/browser-window/",
1299 		E_RESTORE_WINDOW_SIZE);
1300 }
1301 
1302 GtkWidget *
e_mail_browser_new(EMailBackend * backend,EMailFormatterMode display_mode)1303 e_mail_browser_new (EMailBackend *backend,
1304                     EMailFormatterMode display_mode)
1305 {
1306 	g_return_val_if_fail (E_IS_MAIL_BACKEND (backend), NULL);
1307 
1308 	return g_object_new (
1309 		E_TYPE_MAIL_BROWSER,
1310 		"backend", backend,
1311 		"display-mode", display_mode,
1312 		NULL);
1313 }
1314 
1315 void
e_mail_browser_close(EMailBrowser * browser)1316 e_mail_browser_close (EMailBrowser *browser)
1317 {
1318 	g_return_if_fail (E_IS_MAIL_BROWSER (browser));
1319 
1320 	gtk_widget_destroy (GTK_WIDGET (browser));
1321 }
1322 
1323 void
e_mail_browser_ask_close_on_reply(EMailBrowser * browser)1324 e_mail_browser_ask_close_on_reply (EMailBrowser *browser)
1325 {
1326 	EAlertSink *alert_sink;
1327 	EAlert *alert;
1328 	gulong handler_id;
1329 
1330 	g_return_if_fail (E_IS_MAIL_BROWSER (browser));
1331 
1332 	/* Do nothing if the question has already been presented, even if
1333 	 * the user dismissed it without answering.  We only present the
1334 	 * question once per browser window, lest it become annoying. */
1335 	if (browser->priv->close_on_reply_alert != NULL)
1336 		return;
1337 
1338 	alert = e_alert_new ("mail:browser-close-on-reply", NULL);
1339 
1340 	handler_id = g_signal_connect (
1341 		alert, "response",
1342 		G_CALLBACK (mail_browser_close_on_reply_response_cb),
1343 		browser);
1344 
1345 	browser->priv->close_on_reply_alert = g_object_ref (alert);
1346 	browser->priv->close_on_reply_response_handler_id = handler_id;
1347 
1348 	alert_sink = e_mail_reader_get_alert_sink (E_MAIL_READER (browser));
1349 	e_alert_sink_submit_alert (alert_sink, alert);
1350 
1351 	g_object_unref (alert);
1352 }
1353 
1354 EAutomaticActionPolicy
e_mail_browser_get_close_on_reply_policy(EMailBrowser * browser)1355 e_mail_browser_get_close_on_reply_policy (EMailBrowser *browser)
1356 {
1357 	g_return_val_if_fail (
1358 		E_IS_MAIL_BROWSER (browser),
1359 		E_AUTOMATIC_ACTION_POLICY_ASK);
1360 
1361 	return browser->priv->close_on_reply_policy;
1362 }
1363 
1364 void
e_mail_browser_set_close_on_reply_policy(EMailBrowser * browser,EAutomaticActionPolicy policy)1365 e_mail_browser_set_close_on_reply_policy (EMailBrowser *browser,
1366                                           EAutomaticActionPolicy policy)
1367 {
1368 	g_return_if_fail (E_IS_MAIL_BROWSER (browser));
1369 
1370 	if (policy == browser->priv->close_on_reply_policy)
1371 		return;
1372 
1373 	browser->priv->close_on_reply_policy = policy;
1374 
1375 	g_object_notify (G_OBJECT (browser), "close-on-reply-policy");
1376 }
1377 
1378 EMailFormatterMode
e_mail_browser_get_display_mode(EMailBrowser * browser)1379 e_mail_browser_get_display_mode (EMailBrowser *browser)
1380 {
1381 	g_return_val_if_fail (
1382 		E_IS_MAIL_BROWSER (browser),
1383 		E_MAIL_FORMATTER_MODE_INVALID);
1384 
1385 	return browser->priv->display_mode;
1386 }
1387 
1388 EFocusTracker *
e_mail_browser_get_focus_tracker(EMailBrowser * browser)1389 e_mail_browser_get_focus_tracker (EMailBrowser *browser)
1390 {
1391 	g_return_val_if_fail (E_IS_MAIL_BROWSER (browser), NULL);
1392 
1393 	return browser->priv->focus_tracker;
1394 }
1395 
1396 gboolean
e_mail_browser_get_show_deleted(EMailBrowser * browser)1397 e_mail_browser_get_show_deleted (EMailBrowser *browser)
1398 {
1399 	g_return_val_if_fail (E_IS_MAIL_BROWSER (browser), FALSE);
1400 
1401 	return browser->priv->show_deleted;
1402 }
1403 
1404 void
e_mail_browser_set_show_deleted(EMailBrowser * browser,gboolean show_deleted)1405 e_mail_browser_set_show_deleted (EMailBrowser *browser,
1406                                  gboolean show_deleted)
1407 {
1408 	g_return_if_fail (E_IS_MAIL_BROWSER (browser));
1409 
1410 	if (browser->priv->show_deleted == show_deleted)
1411 		return;
1412 
1413 	browser->priv->show_deleted = show_deleted;
1414 
1415 	g_object_notify (G_OBJECT (browser), "show-deleted");
1416 }
1417 
1418 gboolean
e_mail_browser_get_show_junk(EMailBrowser * browser)1419 e_mail_browser_get_show_junk (EMailBrowser *browser)
1420 {
1421 	g_return_val_if_fail (E_IS_MAIL_BROWSER (browser), FALSE);
1422 
1423 	return browser->priv->show_junk;
1424 }
1425 
1426 void
e_mail_browser_set_show_junk(EMailBrowser * browser,gboolean show_junk)1427 e_mail_browser_set_show_junk (EMailBrowser *browser,
1428 			      gboolean show_junk)
1429 {
1430 	g_return_if_fail (E_IS_MAIL_BROWSER (browser));
1431 
1432 	if (browser->priv->show_junk == show_junk)
1433 		return;
1434 
1435 	browser->priv->show_junk = show_junk;
1436 
1437 	g_object_notify (G_OBJECT (browser), "show-junk");
1438 }
1439 
1440 GtkUIManager *
e_mail_browser_get_ui_manager(EMailBrowser * browser)1441 e_mail_browser_get_ui_manager (EMailBrowser *browser)
1442 {
1443 	g_return_val_if_fail (E_IS_MAIL_BROWSER (browser), NULL);
1444 
1445 	return browser->priv->ui_manager;
1446 }
1447 
1448 gboolean
e_mail_browser_get_close_on_delete_or_junk(EMailBrowser * browser)1449 e_mail_browser_get_close_on_delete_or_junk (EMailBrowser *browser)
1450 {
1451 	g_return_val_if_fail (E_IS_MAIL_BROWSER (browser), FALSE);
1452 
1453 	return browser->priv->close_on_delete_or_junk;
1454 }
1455 
1456 void
e_mail_browser_set_close_on_delete_or_junk(EMailBrowser * browser,gboolean close_on_delete_or_junk)1457 e_mail_browser_set_close_on_delete_or_junk (EMailBrowser *browser,
1458 					    gboolean close_on_delete_or_junk)
1459 {
1460 	g_return_if_fail (E_IS_MAIL_BROWSER (browser));
1461 
1462 	if ((browser->priv->close_on_delete_or_junk ? 1 : 0) == (close_on_delete_or_junk ? 1 : 0))
1463 		return;
1464 
1465 	browser->priv->close_on_delete_or_junk = close_on_delete_or_junk;
1466 
1467 	g_object_notify (G_OBJECT (browser), "close-on-delete-or-junk");
1468 }
1469