2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU Lesser General Public License as published by
4 * the Free Software Foundation.
6 * This program is distributed in the hope that it will be useful, but
7 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
8 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * You should have received a copy of the GNU Lesser General Public License
12 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 * Srinivasa Ragavan <sragavan@gnome.org>
18 * Copyright (C) 2010 Intel corporation. (www.intel.com)
22 #include "evolution-config.h"
24 #include <glib/gi18n.h>
26 #include <shell/e-shell-window-actions.h>
28 #include <libemail-engine/libemail-engine.h>
31 #include "message-list.h"
32 #include "e-mail-reader-utils.h"
34 #include "e-mail-paned-view.h"
36 #define E_MAIL_PANED_VIEW_GET_PRIVATE(obj) \
37 (G_TYPE_INSTANCE_GET_PRIVATE \
38 ((obj), E_TYPE_MAIL_PANED_VIEW, EMailPanedViewPrivate))
40 #define E_SHELL_WINDOW_ACTION_GROUP_MAIL(window) \
41 E_SHELL_WINDOW_ACTION_GROUP ((window), "mail")
43 struct _EMailPanedViewPrivate
{
45 GtkWidget
*scrolled_window
;
46 GtkWidget
*message_list
;
47 GtkWidget
*preview_pane
;
48 GtkWidget
*search_bar
;
50 EMailDisplay
*display
;
51 GalViewInstance
*view_instance
;
53 /* ETable scrolling hack */
54 gdouble default_scrollbar_position
;
56 guint paned_binding_id
;
58 /* Signal handler IDs */
59 guint message_list_built_id
;
65 PROP_GROUP_BY_THREADS
,
67 PROP_MARK_SEEN_ALWAYS
,
68 PROP_DELETE_SELECTS_PREVIOUS
71 #define STATE_KEY_GROUP_BY_THREADS "GroupByThreads"
72 #define STATE_KEY_SELECTED_MESSAGE "SelectedMessage"
73 #define STATE_KEY_PREVIEW_VISIBLE "PreviewVisible"
74 #define STATE_GROUP_GLOBAL_FOLDER "GlobalFolder"
76 /* Forward Declarations */
77 static void e_mail_paned_view_reader_init (EMailReaderInterface
*iface
);
79 G_DEFINE_TYPE_WITH_CODE (
80 EMailPanedView
, e_mail_paned_view
, E_TYPE_MAIL_VIEW
,
81 G_IMPLEMENT_INTERFACE (
82 E_TYPE_MAIL_READER
, e_mail_paned_view_reader_init
)
83 G_IMPLEMENT_INTERFACE (
84 E_TYPE_EXTENSIBLE
, NULL
))
87 mail_paned_view_save_boolean (EMailView
*view
,
94 reader
= E_MAIL_READER (view
);
95 folder
= e_mail_reader_ref_folder (reader
);
98 EShellView
*shell_view
;
103 shell_view
= e_mail_view_get_shell_view (view
);
104 key_file
= e_shell_view_get_state_key_file (shell_view
);
106 folder_uri
= e_mail_folder_uri_from_folder (folder
);
107 group_name
= g_strdup_printf ("Folder %s", folder_uri
);
108 g_key_file_set_boolean (key_file
, group_name
, key
, value
);
112 g_key_file_set_boolean (
113 key_file
, STATE_GROUP_GLOBAL_FOLDER
, key
, value
);
115 e_shell_view_set_state_dirty (shell_view
);
117 g_object_unref (folder
);
122 mail_paned_view_message_list_built_cb (EMailView
*view
,
123 MessageList
*message_list
)
125 EMailPanedViewPrivate
*priv
;
126 EShellView
*shell_view
;
127 EShellWindow
*shell_window
;
131 priv
= E_MAIL_PANED_VIEW_GET_PRIVATE (view
);
133 folder
= message_list_ref_folder (message_list
);
135 g_signal_handler_disconnect (
136 message_list
, priv
->message_list_built_id
);
137 priv
->message_list_built_id
= 0;
139 shell_view
= e_mail_view_get_shell_view (view
);
140 shell_window
= e_shell_view_get_shell_window (shell_view
);
142 key_file
= e_shell_view_get_state_key_file (shell_view
);
144 if (message_list
->cursor_uid
!= NULL
)
147 else if (folder
== NULL
)
150 else if (e_shell_window_get_safe_mode (shell_window
))
151 e_shell_window_set_safe_mode (shell_window
, FALSE
);
159 folder_uri
= e_mail_folder_uri_from_folder (folder
);
161 key
= STATE_KEY_SELECTED_MESSAGE
;
162 group_name
= g_strdup_printf ("Folder %s", folder_uri
);
163 uid
= g_key_file_get_string (key_file
, group_name
, key
, NULL
);
168 if (!message_list_contains_uid (message_list
, uid
) &&
169 e_mail_reader_get_mark_seen_always (E_MAIL_READER (view
)))
170 e_mail_reader_unset_folder_just_selected (E_MAIL_READER (view
));
172 /* Use selection fallbacks if UID is not found. */
173 message_list_select_uid (message_list
, uid
, TRUE
);
178 g_clear_object (&folder
);
182 mail_paned_view_message_selected_cb (EMailView
*view
,
183 const gchar
*message_uid
,
184 MessageList
*message_list
)
186 EShellView
*shell_view
;
193 folder
= message_list_ref_folder (message_list
);
195 /* This also gets triggered when selecting a store name on
196 * the sidebar such as "On This Computer", in which case
197 * 'folder' will be NULL. */
201 shell_view
= e_mail_view_get_shell_view (view
);
202 key_file
= e_shell_view_get_state_key_file (shell_view
);
204 folder_uri
= e_mail_folder_uri_from_folder (folder
);
206 key
= STATE_KEY_SELECTED_MESSAGE
;
207 group_name
= g_strdup_printf ("Folder %s", folder_uri
);
209 if (message_uid
!= NULL
)
210 g_key_file_set_string (key_file
, group_name
, key
, message_uid
);
212 g_key_file_remove_key (key_file
, group_name
, key
, NULL
);
213 e_shell_view_set_state_dirty (shell_view
);
218 g_object_unref (folder
);
221 /* To recognize old values from new values */
222 #define PROPORTION_LOWER_LIMIT 1000000
225 mail_paned_view_map_setting_to_proportion_cb (GValue
*value
,
230 gdouble proportion
= 0.5;
232 stored
= g_variant_get_int32 (variant
);
234 if (stored
>= PROPORTION_LOWER_LIMIT
)
235 proportion
= (stored
- PROPORTION_LOWER_LIMIT
) / ((gdouble
) PROPORTION_LOWER_LIMIT
);
237 g_value_set_double (value
, proportion
);
243 mail_paned_view_map_proportion_to_setting_cb (const GValue
*value
,
244 const GVariantType
*expected_type
,
249 proportion
= g_value_get_double (value
);
251 return g_variant_new_int32 (PROPORTION_LOWER_LIMIT
+ (gint32
) (proportion
* PROPORTION_LOWER_LIMIT
));
255 mail_paned_view_notify_orientation_cb (GtkWidget
*paned
,
257 EShellWindow
*shell_window
)
260 const gchar
*settings_key
;
261 guint32 add_flags
= 0;
263 g_return_if_fail (E_IS_PANED (paned
));
264 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window
));
266 g_settings_unbind (paned
, "proportion");
268 if (e_shell_window_is_main_instance (shell_window
)) {
269 if (gtk_orientable_get_orientation (GTK_ORIENTABLE (paned
)) == GTK_ORIENTATION_HORIZONTAL
)
270 settings_key
= "hpaned-size";
272 settings_key
= "paned-size";
274 if (gtk_orientable_get_orientation (GTK_ORIENTABLE (paned
)) == GTK_ORIENTATION_HORIZONTAL
)
275 settings_key
= "hpaned-size-sub";
277 settings_key
= "paned-size-sub";
279 add_flags
= G_SETTINGS_BIND_GET_NO_CHANGES
;
282 settings
= e_util_ref_settings ("org.gnome.evolution.mail");
284 g_settings_bind_with_mapping (settings
, settings_key
,
286 G_SETTINGS_BIND_DEFAULT
| add_flags
,
287 mail_paned_view_map_setting_to_proportion_cb
,
288 mail_paned_view_map_proportion_to_setting_cb
,
291 g_object_unref (settings
);
295 mail_paned_view_restore_state_cb (EShellWindow
*shell_window
,
296 EShellView
*shell_view
,
297 EMailPanedView
*view
)
299 EMailPanedViewPrivate
*priv
;
301 priv
= E_MAIL_PANED_VIEW (view
)->priv
;
303 g_signal_connect (priv
->paned
, "notify::orientation",
304 G_CALLBACK (mail_paned_view_notify_orientation_cb
), shell_window
);
306 mail_paned_view_notify_orientation_cb (priv
->paned
, NULL
, shell_window
);
310 mail_paned_display_view_cb (GalViewInstance
*view_instance
,
315 EShellView
*shell_view
;
316 GtkWidget
*message_list
;
318 shell_view
= e_mail_view_get_shell_view (view
);
319 e_shell_view_set_view_instance (shell_view
, view_instance
);
321 reader
= E_MAIL_READER (view
);
322 message_list
= e_mail_reader_get_message_list (reader
);
324 if (GAL_IS_VIEW_ETABLE (gal_view
))
325 gal_view_etable_attach_tree (
326 GAL_VIEW_ETABLE (gal_view
),
327 E_TREE (message_list
));
331 mail_paned_view_notify_group_by_threads_cb (EMailReader
*reader
)
333 gboolean group_by_threads
;
335 group_by_threads
= e_mail_reader_get_group_by_threads (reader
);
337 mail_paned_view_save_boolean (
338 E_MAIL_VIEW (reader
),
339 STATE_KEY_GROUP_BY_THREADS
, group_by_threads
);
343 mail_paned_view_set_property (GObject
*object
,
348 switch (property_id
) {
349 case PROP_FORWARD_STYLE
:
350 e_mail_reader_set_forward_style (
351 E_MAIL_READER (object
),
352 g_value_get_enum (value
));
355 case PROP_GROUP_BY_THREADS
:
356 e_mail_reader_set_group_by_threads (
357 E_MAIL_READER (object
),
358 g_value_get_boolean (value
));
361 case PROP_REPLY_STYLE
:
362 e_mail_reader_set_reply_style (
363 E_MAIL_READER (object
),
364 g_value_get_enum (value
));
367 case PROP_MARK_SEEN_ALWAYS
:
368 e_mail_reader_set_mark_seen_always (
369 E_MAIL_READER (object
),
370 g_value_get_boolean (value
));
373 case PROP_DELETE_SELECTS_PREVIOUS
:
374 e_mail_reader_set_delete_selects_previous (
375 E_MAIL_READER (object
),
376 g_value_get_boolean (value
));
380 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
384 mail_paned_view_get_property (GObject
*object
,
389 switch (property_id
) {
390 case PROP_FORWARD_STYLE
:
393 e_mail_reader_get_forward_style (
394 E_MAIL_READER (object
)));
397 case PROP_GROUP_BY_THREADS
:
398 g_value_set_boolean (
400 e_mail_reader_get_group_by_threads (
401 E_MAIL_READER (object
)));
404 case PROP_REPLY_STYLE
:
407 e_mail_reader_get_reply_style (
408 E_MAIL_READER (object
)));
411 case PROP_MARK_SEEN_ALWAYS
:
412 g_value_set_boolean (
414 e_mail_reader_get_mark_seen_always (
415 E_MAIL_READER (object
)));
418 case PROP_DELETE_SELECTS_PREVIOUS
:
419 g_value_set_boolean (
421 e_mail_reader_get_delete_selects_previous (
422 E_MAIL_READER (object
)));
426 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
430 mail_paned_view_dispose (GObject
*object
)
432 EMailPanedViewPrivate
*priv
;
434 priv
= E_MAIL_PANED_VIEW_GET_PRIVATE (object
);
436 e_mail_reader_dispose (E_MAIL_READER (object
));
438 if (priv
->paned
!= NULL
) {
439 g_object_unref (priv
->paned
);
443 if (priv
->scrolled_window
!= NULL
) {
444 g_object_unref (priv
->scrolled_window
);
445 priv
->scrolled_window
= NULL
;
448 if (priv
->message_list
!= NULL
) {
449 g_object_unref (priv
->message_list
);
450 priv
->message_list
= NULL
;
453 if (priv
->preview_pane
!= NULL
) {
454 g_object_unref (priv
->preview_pane
);
455 priv
->preview_pane
= NULL
;
458 if (priv
->view_instance
!= NULL
) {
459 g_object_unref (priv
->view_instance
);
460 priv
->view_instance
= NULL
;
463 priv
->display
= NULL
;
465 /* Chain up to parent's dispose() method. */
466 G_OBJECT_CLASS (e_mail_paned_view_parent_class
)->dispose (object
);
469 static GtkActionGroup
*
470 mail_paned_view_get_action_group (EMailReader
*reader
,
471 EMailReaderActionGroup group
)
474 EShellView
*shell_view
;
475 EShellWindow
*shell_window
;
476 const gchar
*group_name
;
478 view
= E_MAIL_VIEW (reader
);
479 shell_view
= e_mail_view_get_shell_view (view
);
480 shell_window
= e_shell_view_get_shell_window (shell_view
);
483 case E_MAIL_READER_ACTION_GROUP_STANDARD
:
486 case E_MAIL_READER_ACTION_GROUP_SEARCH_FOLDERS
:
487 group_name
= "search-folders";
490 g_return_val_if_reached (NULL
);
493 return e_shell_window_get_action_group (shell_window
, group_name
);
497 mail_paned_view_get_alert_sink (EMailReader
*reader
)
500 EShellView
*shell_view
;
501 EShellContent
*shell_content
;
503 view
= E_MAIL_VIEW (reader
);
504 shell_view
= e_mail_view_get_shell_view (view
);
505 shell_content
= e_shell_view_get_shell_content (shell_view
);
507 return E_ALERT_SINK (shell_content
);
510 static EMailBackend
*
511 mail_paned_view_get_backend (EMailReader
*reader
)
514 EShellView
*shell_view
;
515 EShellBackend
*shell_backend
;
517 view
= E_MAIL_VIEW (reader
);
518 shell_view
= e_mail_view_get_shell_view (view
);
519 shell_backend
= e_shell_view_get_shell_backend (shell_view
);
521 return E_MAIL_BACKEND (shell_backend
);
524 static EMailDisplay
*
525 mail_paned_view_get_mail_display (EMailReader
*reader
)
527 EMailPanedViewPrivate
*priv
;
529 priv
= E_MAIL_PANED_VIEW (reader
)->priv
;
531 return priv
->display
;
535 mail_paned_view_get_hide_deleted (EMailReader
*reader
)
537 return !e_mail_view_get_show_deleted (E_MAIL_VIEW (reader
));
541 mail_paned_view_get_message_list (EMailReader
*reader
)
543 EMailPanedView
*paned_view
;
545 paned_view
= E_MAIL_PANED_VIEW (reader
);
547 return paned_view
->priv
->message_list
;
551 mail_paned_view_get_popup_menu (EMailReader
*reader
)
554 EShellView
*shell_view
;
555 EShellWindow
*shell_window
;
556 GtkUIManager
*ui_manager
;
559 view
= E_MAIL_VIEW (reader
);
560 shell_view
= e_mail_view_get_shell_view (view
);
561 shell_window
= e_shell_view_get_shell_window (shell_view
);
563 ui_manager
= e_shell_window_get_ui_manager (shell_window
);
564 widget
= gtk_ui_manager_get_widget (ui_manager
, "/mail-preview-popup");
566 return GTK_MENU (widget
);
569 static EPreviewPane
*
570 mail_paned_view_get_preview_pane (EMailReader
*reader
)
572 EMailPanedView
*paned_view
;
574 paned_view
= E_MAIL_PANED_VIEW (reader
);
576 return E_PREVIEW_PANE (paned_view
->priv
->preview_pane
);
580 mail_paned_view_get_window (EMailReader
*reader
)
583 EShellView
*shell_view
;
584 EShellWindow
*shell_window
;
586 view
= E_MAIL_VIEW (reader
);
587 shell_view
= e_mail_view_get_shell_view (view
);
588 shell_window
= e_shell_view_get_shell_window (shell_view
);
590 return GTK_WINDOW (shell_window
);
594 mail_paned_view_set_folder (EMailReader
*reader
,
597 EMailPanedViewPrivate
*priv
;
600 EShellView
*shell_view
;
601 EShellWindow
*shell_window
;
603 EMailReaderInterface
*default_interface
;
604 GtkWidget
*message_list
;
606 CamelFolder
*previous_folder
;
610 gboolean value
, global_view_setting
;
611 GError
*error
= NULL
;
613 priv
= E_MAIL_PANED_VIEW_GET_PRIVATE (reader
);
615 view
= E_MAIL_VIEW (reader
);
616 shell_view
= e_mail_view_get_shell_view (view
);
618 /* Can be NULL, if the shell window was closed meanwhile */
622 previous_folder
= e_mail_reader_ref_folder (reader
);
623 if (previous_folder
== folder
) {
624 g_clear_object (&previous_folder
);
628 g_clear_object (&previous_folder
);
630 shell_window
= e_shell_view_get_shell_window (shell_view
);
632 shell
= e_shell_window_get_shell (shell_window
);
634 settings
= e_util_ref_settings ("org.gnome.evolution.mail");
636 /* FIXME This should be an EMailReader property. */
637 global_view_setting
= g_settings_get_boolean (
638 settings
, "global-view-setting");
640 message_list
= e_mail_reader_get_message_list (reader
);
642 message_list_freeze (MESSAGE_LIST (message_list
));
644 /* Chain up to interface's default set_folder() method. */
645 default_interface
= g_type_default_interface_peek (E_TYPE_MAIL_READER
);
646 default_interface
->set_folder (reader
, folder
);
651 /* Only refresh the folder if we're online. */
652 if (e_shell_get_online (shell
))
653 e_mail_reader_refresh_folder (reader
, folder
);
655 /* This is a one-time-only callback. */
656 if (MESSAGE_LIST (message_list
)->cursor_uid
== NULL
&&
657 priv
->message_list_built_id
== 0)
658 priv
->message_list_built_id
= g_signal_connect_swapped (
659 message_list
, "message-list-built",
660 G_CALLBACK (mail_paned_view_message_list_built_cb
),
663 /* Restore the folder's preview and threaded state. */
665 folder_uri
= e_mail_folder_uri_from_folder (folder
);
666 key_file
= e_shell_view_get_state_key_file (shell_view
);
667 group_name
= g_strdup_printf ("Folder %s", folder_uri
);
670 key
= STATE_KEY_GROUP_BY_THREADS
;
671 value
= g_key_file_get_boolean (key_file
, global_view_setting
? STATE_GROUP_GLOBAL_FOLDER
: group_name
, key
, &error
);
673 g_clear_error (&error
);
675 value
= !global_view_setting
||
676 g_key_file_get_boolean (key_file
, STATE_GROUP_GLOBAL_FOLDER
, key
, &error
);
678 g_clear_error (&error
);
683 e_mail_reader_set_group_by_threads (reader
, value
);
685 key
= STATE_KEY_PREVIEW_VISIBLE
;
686 value
= g_key_file_get_boolean (key_file
, global_view_setting
? STATE_GROUP_GLOBAL_FOLDER
: group_name
, key
, &error
);
688 g_clear_error (&error
);
690 value
= !global_view_setting
||
691 g_key_file_get_boolean (key_file
, STATE_GROUP_GLOBAL_FOLDER
, key
, &error
);
693 g_clear_error (&error
);
698 /* XXX This is a little confusing and needs rethought. The
699 * EShellWindow:safe-mode property blocks automatic message
700 * selection, but the "safe-list" setting blocks both the
701 * preview pane and automatic message selection. */
702 if (g_settings_get_boolean (settings
, "safe-list")) {
703 g_settings_set_boolean (settings
, "safe-list", FALSE
);
704 e_shell_window_set_safe_mode (shell_window
, TRUE
);
708 e_mail_view_set_preview_visible (E_MAIL_VIEW (reader
), value
);
713 message_list_thaw (MESSAGE_LIST (message_list
));
715 g_object_unref (settings
);
719 mail_paned_view_reader_open_selected_mail (EMailReader
*reader
)
721 EMailPanedView
*paned_view
;
722 EMailPanedViewClass
*class;
724 paned_view
= E_MAIL_PANED_VIEW (reader
);
726 class = E_MAIL_PANED_VIEW_GET_CLASS (paned_view
);
727 g_return_val_if_fail (class->open_selected_mail
!= NULL
, 0);
729 return class->open_selected_mail (paned_view
);
733 mail_paned_view_constructed (GObject
*object
)
735 EMailPanedViewPrivate
*priv
;
736 EShellBackend
*shell_backend
;
737 EShellWindow
*shell_window
;
738 EShellView
*shell_view
;
741 EMailBackend
*backend
;
742 EMailSession
*session
;
744 GtkWidget
*message_list
;
745 GtkWidget
*container
;
746 GtkWidget
*widget
, *vbox
;
748 priv
= E_MAIL_PANED_VIEW_GET_PRIVATE (object
);
750 view
= E_MAIL_VIEW (object
);
751 shell_view
= e_mail_view_get_shell_view (view
);
752 shell_window
= e_shell_view_get_shell_window (shell_view
);
753 shell_backend
= e_shell_view_get_shell_backend (shell_view
);
755 backend
= E_MAIL_BACKEND (shell_backend
);
756 session
= e_mail_backend_get_session (backend
);
758 priv
->display
= g_object_new (E_TYPE_MAIL_DISPLAY
,
759 "headers-collapsable", TRUE
,
760 "remote-content", e_mail_backend_get_remote_content (backend
),
763 /* FIXME This should be an EMailPanedView property, so
764 * it can be configured from the settings module. */
766 settings
= e_util_ref_settings ("org.gnome.evolution.mail");
769 settings
, "headers-collapsed",
770 priv
->display
, "headers-collapsed",
771 G_SETTINGS_BIND_DEFAULT
);
773 g_object_unref (settings
);
775 /* Build content widgets. */
777 container
= GTK_WIDGET (object
);
779 widget
= e_paned_new (GTK_ORIENTATION_VERTICAL
);
780 e_paned_set_fixed_resize (E_PANED (widget
), FALSE
);
781 gtk_box_pack_start (GTK_BOX (container
), widget
, TRUE
, TRUE
, 0);
782 priv
->paned
= g_object_ref (widget
);
783 gtk_widget_show (widget
);
785 e_binding_bind_property (
786 object
, "orientation",
787 widget
, "orientation",
788 G_BINDING_SYNC_CREATE
);
790 container
= priv
->paned
;
792 widget
= gtk_scrolled_window_new (NULL
, NULL
);
793 gtk_scrolled_window_set_policy (
794 GTK_SCROLLED_WINDOW (widget
),
795 GTK_POLICY_NEVER
, GTK_POLICY_ALWAYS
);
796 gtk_paned_pack1 (GTK_PANED (container
), widget
, TRUE
, FALSE
);
797 priv
->scrolled_window
= g_object_ref (widget
);
798 gtk_widget_show (widget
);
802 widget
= message_list_new (session
);
803 gtk_container_add (GTK_CONTAINER (container
), widget
);
804 priv
->message_list
= g_object_ref (widget
);
805 gtk_widget_show (widget
);
807 container
= priv
->paned
;
809 vbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 2);
810 widget
= e_preview_pane_new (E_WEB_VIEW (priv
->display
));
812 gtk_box_pack_start (GTK_BOX (vbox
), widget
, TRUE
, TRUE
, 0);
813 gtk_box_pack_start (GTK_BOX (vbox
), GTK_WIDGET (e_mail_display_get_attachment_view (priv
->display
)), FALSE
, FALSE
, 0);
815 gtk_paned_pack2 (GTK_PANED (container
), vbox
, FALSE
, FALSE
);
816 priv
->preview_pane
= g_object_ref (widget
);
817 gtk_widget_show (GTK_WIDGET (priv
->display
));
818 gtk_widget_show (widget
);
820 e_binding_bind_property (
821 object
, "preview-visible",
823 G_BINDING_SYNC_CREATE
);
825 e_binding_bind_property (
826 object
, "preview-visible",
828 G_BINDING_SYNC_CREATE
);
830 /* Load the view instance. */
832 e_mail_view_update_view_instance (E_MAIL_VIEW (object
));
834 /* Message list customizations. */
836 e_mail_reader_init (E_MAIL_READER (object
), FALSE
, TRUE
);
838 reader
= E_MAIL_READER (object
);
839 message_list
= e_mail_reader_get_message_list (reader
);
841 g_signal_connect_swapped (
842 message_list
, "message-selected",
843 G_CALLBACK (mail_paned_view_message_selected_cb
),
846 /* Restore pane positions from the last session once
847 * the shell view is fully initialized and visible. */
849 shell_window
, "shell-view-created::mail",
850 G_CALLBACK (mail_paned_view_restore_state_cb
),
853 /* Do this after creating the message list. Our
854 * set_preview_visible() method relies on it. */
855 e_mail_view_set_preview_visible (view
, TRUE
);
857 e_mail_reader_connect_remote_content (reader
);
859 e_extensible_load_extensions (E_EXTENSIBLE (object
));
861 /* Chain up to parent's constructed() method. */
862 G_OBJECT_CLASS (e_mail_paned_view_parent_class
)->constructed (object
);
866 mail_paned_view_set_search_strings (EMailView
*view
,
867 GSList
*search_strings
)
869 EMailDisplay
*display
;
873 reader
= E_MAIL_READER (view
);
874 display
= e_mail_reader_get_mail_display (reader
);
878 web_view
= E_WEB_VIEW (display
);
880 e_web_view_clear_highlights (web_view
);
882 while (search_strings
!= NULL
) {
883 e_web_view_add_highlight (web_view
, search_strings
->data
);
884 search_strings
= g_slist_next (search_strings
);
888 static GalViewInstance
*
889 mail_paned_view_get_view_instance (EMailView
*view
)
891 EMailPanedView
*paned_view
;
893 paned_view
= E_MAIL_PANED_VIEW (view
);
895 return paned_view
->priv
->view_instance
;
899 empv_create_view_id (CamelFolder
*folder
)
902 gchar
*res
, *folder_uri
;
904 g_return_val_if_fail (folder
!= NULL
, NULL
);
906 folder_uri
= e_mail_folder_uri_from_folder (folder
);
907 g_return_val_if_fail (folder_uri
!= NULL
, NULL
);
909 /* to be able to migrate previously saved views */
910 e_filename_make_safe (folder_uri
);
912 /* use MD5 checksum of the folder URI, to not depend on its length */
913 checksum
= g_checksum_new (G_CHECKSUM_MD5
);
914 g_checksum_update (checksum
, (const guchar
*) folder_uri
, -1);
916 res
= g_strdup (g_checksum_get_string (checksum
));
918 g_checksum_free (checksum
);
925 empv_folder_or_parent_is_outgoing (MailFolderCache
*folder_cache
,
927 const gchar
*fullname
)
929 CamelFolderInfoFlags info_flags
;
931 gboolean res
= FALSE
;
933 g_return_val_if_fail (MAIL_IS_FOLDER_CACHE (folder_cache
), FALSE
);
934 g_return_val_if_fail (CAMEL_IS_STORE (store
), FALSE
);
935 g_return_val_if_fail (fullname
!= NULL
, FALSE
);
937 if (!mail_folder_cache_get_folder_info_flags (folder_cache
, store
, fullname
, &info_flags
))
940 if ((info_flags
& CAMEL_FOLDER_TYPE_MASK
) == CAMEL_FOLDER_TYPE_OUTBOX
||
941 (info_flags
& CAMEL_FOLDER_TYPE_MASK
) == CAMEL_FOLDER_TYPE_SENT
)
944 dash
= strrchr (fullname
, '/');
948 path
= g_strdup (fullname
);
950 while (path
&& *path
) {
951 dash
= strrchr (path
, '/');
957 if (!mail_folder_cache_get_folder_info_flags (folder_cache
, store
, path
, &info_flags
))
960 if ((info_flags
& CAMEL_FOLDER_TYPE_MASK
) == CAMEL_FOLDER_TYPE_OUTBOX
||
961 (info_flags
& CAMEL_FOLDER_TYPE_MASK
) == CAMEL_FOLDER_TYPE_SENT
) {
973 mail_paned_view_update_view_instance (EMailView
*view
)
975 EMailPanedViewPrivate
*priv
;
978 EShellView
*shell_view
;
979 EShellWindow
*shell_window
;
980 EShellViewClass
*shell_view_class
;
981 ESourceRegistry
*registry
;
982 GalViewCollection
*view_collection
;
983 GalViewInstance
*view_instance
;
984 MailFolderCache
*folder_cache
;
986 GtkOrientable
*orientable
;
987 GtkOrientation orientation
;
989 gboolean outgoing_folder
;
990 gboolean show_vertical_view
;
991 gboolean global_view_setting
;
994 priv
= E_MAIL_PANED_VIEW_GET_PRIVATE (view
);
996 shell_view
= e_mail_view_get_shell_view (view
);
997 shell_view_class
= E_SHELL_VIEW_GET_CLASS (shell_view
);
998 view_collection
= shell_view_class
->view_collection
;
1000 shell_window
= e_shell_view_get_shell_window (shell_view
);
1001 shell
= e_shell_window_get_shell (shell_window
);
1002 registry
= e_shell_get_registry (shell
);
1004 reader
= E_MAIL_READER (view
);
1005 folder
= e_mail_reader_ref_folder (reader
);
1007 /* If no folder is selected, return silently. */
1011 if (priv
->view_instance
!= NULL
) {
1012 g_object_unref (priv
->view_instance
);
1013 priv
->view_instance
= NULL
;
1016 view_id
= empv_create_view_id (folder
);
1017 e_filename_make_safe (view_id
);
1019 folder_cache
= e_mail_session_get_folder_cache (e_mail_backend_get_session (e_mail_reader_get_backend (reader
)));
1022 empv_folder_or_parent_is_outgoing (folder_cache
, camel_folder_get_parent_store (folder
), camel_folder_get_full_name (folder
)) ||
1023 em_utils_folder_is_drafts (registry
, folder
) ||
1024 em_utils_folder_is_outbox (registry
, folder
) ||
1025 em_utils_folder_is_sent (registry
, folder
);
1027 settings
= e_util_ref_settings ("org.gnome.evolution.mail");
1028 global_view_setting
= g_settings_get_boolean (
1029 settings
, "global-view-setting");
1030 g_object_unref (settings
);
1032 if (global_view_setting
) {
1033 if (outgoing_folder
) {
1034 view_instance
= e_shell_view_new_view_instance (
1035 shell_view
, "global_view_sent_setting");
1037 view_instance
= e_shell_view_new_view_instance (
1038 shell_view
, "global_view_setting");
1041 view_instance
= e_shell_view_new_view_instance (
1042 shell_view
, view_id
);
1045 priv
->view_instance
= g_object_ref (view_instance
);
1047 orientable
= GTK_ORIENTABLE (view
);
1048 orientation
= gtk_orientable_get_orientation (orientable
);
1049 show_vertical_view
=
1050 !global_view_setting
&&
1051 (orientation
== GTK_ORIENTATION_HORIZONTAL
);
1053 if (show_vertical_view
) {
1054 const gchar
*user_directory
;
1057 /* Force the view instance into vertical view. */
1059 g_free (view_instance
->custom_filename
);
1060 g_free (view_instance
->current_view_filename
);
1062 user_directory
= gal_view_collection_get_user_directory (
1065 filename
= g_strdup_printf (
1066 "custom_wide_view-%s.xml", view_id
);
1067 view_instance
->custom_filename
=
1068 g_build_filename (user_directory
, filename
, NULL
);
1071 filename
= g_strdup_printf (
1072 "current_wide_view-%s.xml", view_id
);
1073 view_instance
->current_view_filename
=
1074 g_build_filename (user_directory
, filename
, NULL
);
1080 if (outgoing_folder
) {
1081 if (show_vertical_view
)
1082 gal_view_instance_set_default_view (
1083 view_instance
, "Wide_View_Sent");
1085 gal_view_instance_set_default_view (
1086 view_instance
, "As_Sent_Folder");
1087 } else if (show_vertical_view
) {
1088 gal_view_instance_set_default_view (
1089 view_instance
, "Wide_View_Normal");
1092 gal_view_instance_load (view_instance
);
1094 if (!gal_view_instance_exists (view_instance
)) {
1095 gchar
*state_filename
;
1097 state_filename
= mail_config_folder_to_cachename (
1098 folder
, "et-header-");
1100 if (g_file_test (state_filename
, G_FILE_TEST_IS_REGULAR
)) {
1103 view
= gal_view_etable_new ("");
1105 /* XXX This only stashes the filename in the view.
1106 * The state file is not actually loaded until
1107 * the MessageList is attached to the view. */
1108 gal_view_load (view
, state_filename
);
1110 gal_view_instance_set_custom_view (
1111 view_instance
, view
);
1113 g_object_unref (view
);
1116 g_free (state_filename
);
1120 view_instance
, "display-view",
1121 G_CALLBACK (mail_paned_display_view_cb
), view
);
1123 mail_paned_display_view_cb (
1125 gal_view_instance_get_current_view (view_instance
),
1128 view_id
= gal_view_instance_get_current_view_id (view_instance
);
1129 e_shell_view_set_view_id (shell_view
, view_id
);
1132 g_object_unref (view_instance
);
1134 g_clear_object (&folder
);
1138 mail_paned_view_set_preview_visible (EMailView
*view
,
1139 gboolean preview_visible
)
1141 EMailViewClass
*parent_class
;
1143 /* If we're showing the preview, tell EMailReader to reload the
1144 * selected message. This should force it to download the full
1145 * message if necessary, so we don't get an empty preview. */
1146 if (preview_visible
) {
1147 EMailReader
*reader
;
1148 GtkWidget
*message_list
;
1149 const gchar
*cursor_uid
;
1151 reader
= E_MAIL_READER (view
);
1152 message_list
= e_mail_reader_get_message_list (reader
);
1153 cursor_uid
= MESSAGE_LIST (message_list
)->cursor_uid
;
1155 if (cursor_uid
!= NULL
)
1156 e_mail_reader_set_message (reader
, cursor_uid
);
1159 mail_paned_view_save_boolean (
1161 STATE_KEY_PREVIEW_VISIBLE
, preview_visible
);
1163 /* Chain up to parent's set_preview_visible() method. */
1164 parent_class
= E_MAIL_VIEW_CLASS (e_mail_paned_view_parent_class
);
1165 parent_class
->set_preview_visible (view
, preview_visible
);
1169 mail_paned_view_open_selected_mail (EMailPanedView
*view
)
1171 return e_mail_reader_open_selected (E_MAIL_READER (view
));
1175 e_mail_paned_view_class_init (EMailPanedViewClass
*class)
1177 GObjectClass
*object_class
;
1178 EMailViewClass
*mail_view_class
;
1180 g_type_class_add_private (class, sizeof (EMailPanedViewPrivate
));
1182 object_class
= G_OBJECT_CLASS (class);
1183 object_class
->dispose
= mail_paned_view_dispose
;
1184 object_class
->constructed
= mail_paned_view_constructed
;
1185 object_class
->set_property
= mail_paned_view_set_property
;
1186 object_class
->get_property
= mail_paned_view_get_property
;
1188 mail_view_class
= E_MAIL_VIEW_CLASS (class);
1189 mail_view_class
->set_search_strings
= mail_paned_view_set_search_strings
;
1190 mail_view_class
->get_view_instance
= mail_paned_view_get_view_instance
;
1191 mail_view_class
->update_view_instance
= mail_paned_view_update_view_instance
;
1193 mail_view_class
->set_preview_visible
= mail_paned_view_set_preview_visible
;
1195 class->open_selected_mail
= mail_paned_view_open_selected_mail
;
1197 /* Inherited from EMailReader */
1198 g_object_class_override_property (
1203 /* Inherited from EMailReader */
1204 g_object_class_override_property (
1206 PROP_GROUP_BY_THREADS
,
1207 "group-by-threads");
1209 /* Inherited from EMailReader */
1210 g_object_class_override_property (
1215 /* Inherited from EMailReader */
1216 g_object_class_override_property (
1218 PROP_MARK_SEEN_ALWAYS
,
1219 "mark-seen-always");
1221 /* Inherited from EMailReader */
1222 g_object_class_override_property (
1224 PROP_DELETE_SELECTS_PREVIOUS
,
1225 "delete-selects-previous");
1229 e_mail_paned_view_reader_init (EMailReaderInterface
*iface
)
1231 iface
->get_action_group
= mail_paned_view_get_action_group
;
1232 iface
->get_alert_sink
= mail_paned_view_get_alert_sink
;
1233 iface
->get_backend
= mail_paned_view_get_backend
;
1234 iface
->get_mail_display
= mail_paned_view_get_mail_display
;
1235 iface
->get_hide_deleted
= mail_paned_view_get_hide_deleted
;
1236 iface
->get_message_list
= mail_paned_view_get_message_list
;
1237 iface
->get_popup_menu
= mail_paned_view_get_popup_menu
;
1238 iface
->get_preview_pane
= mail_paned_view_get_preview_pane
;
1239 iface
->get_window
= mail_paned_view_get_window
;
1240 iface
->set_folder
= mail_paned_view_set_folder
;
1241 iface
->open_selected_mail
= mail_paned_view_reader_open_selected_mail
;
1245 e_mail_paned_view_init (EMailPanedView
*view
)
1247 view
->priv
= E_MAIL_PANED_VIEW_GET_PRIVATE (view
);
1249 e_signal_connect_notify (
1250 view
, "notify::group-by-threads",
1251 G_CALLBACK (mail_paned_view_notify_group_by_threads_cb
),
1256 e_mail_paned_view_new (EShellView
*shell_view
)
1258 g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view
), NULL
);
1260 return g_object_new (
1261 E_TYPE_MAIL_PANED_VIEW
,
1262 "shell-view", shell_view
, NULL
);
1266 e_mail_paned_view_hide_message_list_pane (EMailPanedView
*view
,
1269 g_return_if_fail (E_IS_MAIL_PANED_VIEW (view
));
1272 gtk_widget_show (view
->priv
->scrolled_window
);
1274 gtk_widget_hide (view
->priv
->scrolled_window
);
1278 e_mail_paned_view_get_preview (EMailPanedView
*view
)
1280 g_return_val_if_fail (E_IS_MAIL_PANED_VIEW (view
), NULL
);
1282 return GTK_WIDGET (mail_paned_view_get_mail_display (E_MAIL_READER (view
)));