diff options
Diffstat (limited to 'mail/e-mail-paned-view.c')
-rw-r--r-- | mail/e-mail-paned-view.c | 573 |
1 files changed, 526 insertions, 47 deletions
diff --git a/mail/e-mail-paned-view.c b/mail/e-mail-paned-view.c index 3840c79606..9aed306b45 100644 --- a/mail/e-mail-paned-view.c +++ b/mail/e-mail-paned-view.c @@ -27,7 +27,9 @@ #include <glib.h> #include <glib/gi18n.h> -#include "e-mail-pane.h" +#include "e-mail-paned-view.h" + +#include <libedataserver/e-data-server-util.h> #include "e-util/e-util-private.h" #include "e-util/e-binding.h" @@ -38,14 +40,19 @@ #include "widgets/misc/e-preview-pane.h" #include "widgets/misc/e-search-bar.h" +#include <shell/e-shell-window-actions.h> + #include "em-utils.h" #include "mail-config.h" #include "mail-ops.h" #include "message-list.h" +#include "e-mail-reader-utils.h" -G_DEFINE_TYPE (EMailPanedView, e_mail_paned_view, GTK_TYPE_VBOX) -struct _EMailPanePrivate { +#define E_SHELL_WINDOW_ACTION_GROUP_MAIL(window) \ + E_SHELL_WINDOW_ACTION_GROUP ((window), "mail") + +struct _EMailPanedViewPrivate { GtkWidget *paned; GtkWidget *scrolled_window; GtkWidget *message_list; @@ -68,11 +75,6 @@ struct _EMailPanePrivate { }; enum { - PANE_CLOSE, - LAST_SIGNAL -}; - -enum { PROP_0, PROP_GROUP_BY_THREADS, PROP_ORIENTATION, @@ -80,12 +82,253 @@ enum { PROP_SHOW_DELETED }; -static guint signals[LAST_SIGNAL] = { 0 }; +#define STATE_KEY_GROUP_BY_THREADS "GroupByThreads" +#define STATE_KEY_SELECTED_MESSAGE "SelectedMessage" +#define STATE_KEY_PREVIEW_VISIBLE "PreviewVisible" + + +static gpointer parent_class; +static GType mail_paned_view_type; static void -e_mail_paned_view_init (EMailPanedView *shell) +mail_paned_view_save_boolean (EMailPanedView *view, + const gchar *key, + gboolean value) { - shell->priv = g_new0(EMailPanedViewPrivate, 1); + EShellView *shell_view; + EShellContent *shell_content; + EMailReader *reader; + GKeyFile *key_file; + const gchar *folder_uri; + gchar *group_name; + + shell_content = E_MAIL_VIEW (view)->content; + shell_view = e_shell_content_get_shell_view (shell_content); + key_file = e_shell_view_get_state_key_file (shell_view); + + reader = E_MAIL_READER (view); + folder_uri = e_mail_reader_get_folder_uri (reader); + + if (folder_uri == NULL) + return; + + group_name = g_strdup_printf ("Folder %s", folder_uri); + g_key_file_set_boolean (key_file, group_name, key, value); + g_free (group_name); + + e_shell_view_set_state_dirty (shell_view); +} + +static void +mail_paned_view_message_list_built_cb (EMailPanedView *view, + MessageList *message_list) +{ + EMailPanedViewPrivate *priv = view->priv; + EShellView *shell_view; + EShellWindow *shell_window; + EShellContent *shell_content; + GKeyFile *key_file; + + g_signal_handler_disconnect ( + message_list, priv->message_list_built_id); + priv->message_list_built_id = 0; + + shell_content = E_MAIL_VIEW (view)->content; + shell_view = e_shell_content_get_shell_view (shell_content); + shell_window = e_shell_view_get_shell_window (shell_view); + + key_file = e_shell_view_get_state_key_file (shell_view); + + if (message_list->cursor_uid != NULL) + ; /* do nothing */ + + else if (message_list->folder_uri == NULL) + ; /* do nothing */ + + else if (e_shell_window_get_safe_mode (shell_window)) + e_shell_window_set_safe_mode (shell_window, FALSE); + + else { + const gchar *folder_uri; + const gchar *key; + gchar *group_name; + gchar *uid; + + key = STATE_KEY_SELECTED_MESSAGE; + folder_uri = message_list->folder_uri; + group_name = g_strdup_printf ("Folder %s", folder_uri); + uid = g_key_file_get_string (key_file, group_name, key, NULL); + g_free (group_name); + + /* Use selection fallbacks if UID is not found. */ + message_list_select_uid (message_list, uid, TRUE); + + g_free (uid); + } +} + +static void +mail_paned_view_message_selected_cb (EMailPanedView *view, + const gchar *message_uid, + MessageList *message_list) +{ + EShellContent *shell_content; + EShellView *shell_view; + GKeyFile *key_file; + const gchar *folder_uri; + const gchar *key; + gchar *group_name; + + folder_uri = message_list->folder_uri; + + /* This also gets triggered when selecting a store name on + * the sidebar such as "On This Computer", in which case + * 'folder_uri' will be NULL. */ + if (folder_uri == NULL) + return; + + shell_content = E_MAIL_VIEW (view)->content; + shell_view = e_shell_content_get_shell_view (shell_content); + key_file = e_shell_view_get_state_key_file (shell_view); + + key = STATE_KEY_SELECTED_MESSAGE; + group_name = g_strdup_printf ("Folder %s", folder_uri); + + if (message_uid != NULL) + g_key_file_set_string (key_file, group_name, key, message_uid); + else + g_key_file_remove_key (key_file, group_name, key, NULL); + e_shell_view_set_state_dirty (shell_view); + + g_free (group_name); +} + +static void +mail_paned_view_restore_state_cb (EShellWindow *shell_window, + EShellView *shell_view, + EMailPanedView *view) +{ + EMailPanedViewPrivate *priv; + GConfBridge *bridge; + GObject *object; + const gchar *key; + + priv = view->priv; + + /* Bind GObject properties to GConf keys. */ + + bridge = gconf_bridge_get (); + + object = G_OBJECT (priv->paned); + key = "/apps/evolution/mail/display/hpaned_size"; + gconf_bridge_bind_property (bridge, key, object, "hposition"); + + object = G_OBJECT (priv->paned); + key = "/apps/evolution/mail/display/paned_size"; + gconf_bridge_bind_property (bridge, key, object, "vposition"); +} + +static void +mail_paned_view_notify_group_by_threads_cb (EMailReader *reader) +{ + gboolean group_by_threads; + + group_by_threads = e_mail_reader_get_group_by_threads (reader); + + mail_paned_view_save_boolean ( + E_MAIL_PANED_VIEW (reader), + STATE_KEY_GROUP_BY_THREADS, group_by_threads); +} + +static GtkOrientation +mail_paned_view_get_orientation (EMailPanedView *view) +{ + return view->priv->orientation; +} + +static void +mail_paned_view_set_orientation (EMailPanedView *view, + GtkOrientation orientation) +{ + view->priv->orientation = orientation; + + g_object_notify (G_OBJECT (view), "orientation"); + + e_mail_paned_view_update_view_instance (view); +} + +static void +mail_paned_view_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_GROUP_BY_THREADS: + e_mail_reader_set_group_by_threads ( + E_MAIL_READER (object), + g_value_get_boolean (value)); + return; + + case PROP_ORIENTATION: + mail_paned_view_set_orientation ( + E_MAIL_PANED_VIEW (object), + g_value_get_enum (value)); + return; + + case PROP_PREVIEW_VISIBLE: + e_mail_paned_view_set_preview_visible ( + E_MAIL_PANED_VIEW (object), + g_value_get_boolean (value)); + return; + + case PROP_SHOW_DELETED: + e_mail_paned_view_set_show_deleted ( + E_MAIL_PANED_VIEW (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +mail_paned_view_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_GROUP_BY_THREADS: + g_value_set_boolean ( + value, + e_mail_reader_get_group_by_threads ( + E_MAIL_READER (object))); + return; + + case PROP_ORIENTATION: + g_value_set_enum ( + value, + mail_paned_view_get_orientation ( + E_MAIL_PANED_VIEW (object))); + return; + + case PROP_PREVIEW_VISIBLE: + g_value_set_boolean ( + value, + e_mail_paned_view_get_preview_visible ( + E_MAIL_PANED_VIEW (object))); + return; + + case PROP_SHOW_DELETED: + g_value_set_boolean ( + value, + e_mail_paned_view_get_show_deleted ( + E_MAIL_PANED_VIEW (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } static void @@ -129,6 +372,191 @@ mail_paned_view_dispose (GObject *object) G_OBJECT_CLASS (parent_class)->dispose (object); } +static GtkActionGroup * +mail_paned_view_get_action_group (EMailReader *reader) +{ + EShellContent *shell_content; + EShellWindow *shell_window; + EShellView *shell_view; + + shell_content = E_MAIL_VIEW (reader)->content; + shell_view = e_shell_content_get_shell_view (shell_content); + shell_window = e_shell_view_get_shell_window (shell_view); + + return E_SHELL_WINDOW_ACTION_GROUP_MAIL (shell_window); +} + +static EMFormatHTML * +mail_paned_view_get_formatter (EMailReader *reader) +{ + EMailPanedViewPrivate *priv; + + priv = E_MAIL_PANED_VIEW (reader)->priv; + + return EM_FORMAT_HTML (priv->formatter); +} + +static gboolean +mail_paned_view_get_hide_deleted (EMailReader *reader) +{ + return !e_mail_paned_view_get_show_deleted (E_MAIL_PANED_VIEW(reader)); +} + +static GtkWidget * +mail_paned_view_get_message_list (EMailReader *reader) +{ + EMailPanedViewPrivate *priv; + + priv = E_MAIL_PANED_VIEW (reader)->priv; + + return priv->message_list; +} + +static GtkMenu * +mail_paned_view_get_popup_menu (EMailReader *reader) +{ + EShellView *shell_view; + EShellWindow *shell_window; + EShellContent *shell_content; + GtkUIManager *ui_manager; + GtkWidget *widget; + + shell_content = E_MAIL_VIEW (reader)->content; + shell_view = e_shell_content_get_shell_view (shell_content); + shell_window = e_shell_view_get_shell_window (shell_view); + + ui_manager = e_shell_window_get_ui_manager (shell_window); + widget = gtk_ui_manager_get_widget (ui_manager, "/mail-preview-popup"); + + return GTK_MENU (widget); +} + +static EShellBackend * +mail_paned_view_get_shell_backend (EMailReader *reader) +{ + EShellContent *shell_content; + EShellView *shell_view; + + shell_content = E_MAIL_VIEW (reader)->content; + shell_view = e_shell_content_get_shell_view (shell_content); + + return e_shell_view_get_shell_backend (shell_view); +} + +static GtkWindow * +mail_paned_view_get_window (EMailReader *reader) +{ + EShellContent *shell_content; + EShellWindow *shell_window; + EShellView *shell_view; + + shell_content = E_MAIL_VIEW (reader)->content; + shell_view = e_shell_content_get_shell_view (shell_content); + shell_window = e_shell_view_get_shell_window (shell_view); + + return GTK_WINDOW (shell_window); +} + +static void +mail_paned_view_set_folder (EMailReader *reader, + CamelFolder *folder, + const gchar *folder_uri) +{ + EShell *shell; + EShellView *shell_view; + EShellWindow *shell_window; + EShellContent *shell_content; + EShellSettings *shell_settings; + EMailPanedViewPrivate *priv; + EMailReaderIface *default_iface; + GtkWidget *message_list; + GKeyFile *key_file; + gchar *group_name; + const gchar *key; + gboolean value; + GError *error = NULL; + + priv = E_MAIL_PANED_VIEW (reader)->priv; + + shell_content = E_MAIL_VIEW (reader)->content; + shell_view = e_shell_content_get_shell_view (shell_content); + shell_window = e_shell_view_get_shell_window (shell_view); + + shell = e_shell_window_get_shell (shell_window); + shell_settings = e_shell_get_shell_settings (shell); + + message_list = e_mail_reader_get_message_list (reader); + + message_list_freeze (MESSAGE_LIST (message_list)); + + /* Chain up to interface's default set_folder() method. */ + default_iface = g_type_default_interface_peek (E_TYPE_MAIL_READER); + default_iface->set_folder (reader, folder, folder_uri); + + if (folder == NULL) + goto exit; + + mail_refresh_folder (folder, NULL, NULL); + + /* This is a one-time-only callback. */ + if (MESSAGE_LIST (message_list)->cursor_uid == NULL && + priv->message_list_built_id == 0) + priv->message_list_built_id = g_signal_connect_swapped ( + message_list, "message-list-built", + G_CALLBACK (mail_paned_view_message_list_built_cb), + reader); + + /* Restore the folder's preview and threaded state. */ + + key_file = e_shell_view_get_state_key_file (shell_view); + group_name = g_strdup_printf ("Folder %s", folder_uri); + + key = STATE_KEY_GROUP_BY_THREADS; + value = g_key_file_get_boolean (key_file, group_name, key, &error); + if (error != NULL) { + value = TRUE; + g_clear_error (&error); + } + + e_mail_reader_set_group_by_threads (reader, value); + + key = STATE_KEY_PREVIEW_VISIBLE; + value = g_key_file_get_boolean (key_file, group_name, key, &error); + if (error != NULL) { + value = TRUE; + g_clear_error (&error); + } + + /* XXX This is a little confusing and needs rethought. The + * EShellWindow:safe-mode property blocks automatic message + * selection, but the "mail-safe-list" shell setting blocks + * both the preview pane and automatic message selection. */ + if (e_shell_settings_get_boolean (shell_settings, "mail-safe-list")) { + e_shell_settings_set_boolean ( + shell_settings, "mail-safe-list", FALSE); + e_shell_window_set_safe_mode (shell_window, TRUE); + value = FALSE; + } + + e_mail_paned_view_set_preview_visible ( + E_MAIL_PANED_VIEW (reader), value); + + g_free (group_name); + +exit: + message_list_thaw (MESSAGE_LIST (message_list)); +} + +static void +mail_paned_view_show_search_bar (EMailReader *reader) +{ + EMailPanedViewPrivate *priv; + + priv = E_MAIL_PANED_VIEW (reader)->priv; + + gtk_widget_show (priv->search_bar); +} + static void mail_paned_view_constructed (GObject *object) { @@ -207,48 +635,53 @@ mail_paned_view_constructed (GObject *object) /* Load the view instance. */ - e_mail_shell_content_update_view_instance ( - E_MAIL_SHELL_CONTENT (shell_content)); + e_mail_paned_view_update_view_instance ( + E_MAIL_PANED_VIEW (object)); /* Message list customizations. */ - reader = E_MAIL_READER (shell_content); + reader = E_MAIL_READER (object); message_list = e_mail_reader_get_message_list (reader); g_signal_connect_swapped ( message_list, "message-selected", - G_CALLBACK (mail_shell_content_message_selected_cb), - shell_content); + G_CALLBACK (mail_paned_view_message_selected_cb), + object); /* Restore pane positions from the last session once * the shell view is fully initialized and visible. */ g_signal_connect ( shell_window, "shell-view-created::mail", - G_CALLBACK (mail_shell_content_restore_state_cb), - shell_content); + G_CALLBACK (mail_paned_view_restore_state_cb), + object); e_mail_reader_connect_headers (reader); } static void -e_mail_paned_view_class_init (EMailPanedViewClass *klass) +mail_paned_view_init (EMailPanedView *shell) +{ + shell->priv = g_new0(EMailPanedViewPrivate, 1); + + shell->priv->preview_visible = TRUE; + + g_signal_connect ( + shell, "notify::group-by-threads", + G_CALLBACK (mail_paned_view_notify_group_by_threads_cb), + NULL); + +} + +static void +mail_paned_view_class_init (EMailPanedViewClass *klass) { GObjectClass * object_class = G_OBJECT_CLASS (klass); - e_mail_paned_view_parent_class = g_type_class_peek_parent (klass); - object_class->finalize = e_mail_paned_view_finalize; + parent_class = g_type_class_peek_parent (klass); object_class->dispose = mail_paned_view_dispose; object_class->constructed = mail_paned_view_constructed; - - - signals[PANE_CLOSE] = - g_signal_new ("pane-close", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EMailPanedViewClass , view_close), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + object_class->set_property = mail_paned_view_set_property; + object_class->get_property = mail_paned_view_get_property; /* Inherited from EMailReader */ @@ -282,26 +715,74 @@ e_mail_paned_view_class_init (EMailPanedViewClass *klass) } static void -mail_pane_reader_init (EMailReaderIface *iface) +mail_paned_view_reader_init (EMailReaderIface *iface) +{ + iface->get_action_group = mail_paned_view_get_action_group; + iface->get_formatter = mail_paned_view_get_formatter; + iface->get_hide_deleted = mail_paned_view_get_hide_deleted; + iface->get_message_list = mail_paned_view_get_message_list; + iface->get_popup_menu = mail_paned_view_get_popup_menu; + iface->get_shell_backend = mail_paned_view_get_shell_backend; + iface->get_window = mail_paned_view_get_window; + iface->set_folder = mail_paned_view_set_folder; + iface->show_search_bar = mail_paned_view_show_search_bar; +} + +GType +e_mail_paned_view_get_type (void) { - iface->get_action_group = mail_pane_get_action_group; - iface->get_formatter = mail_pane_get_formatter; - iface->get_hide_deleted = mail_pane_get_hide_deleted; - iface->get_message_list = mail_pane_get_message_list; - iface->get_popup_menu = mail_pane_get_popup_menu; - iface->get_shell_backend = mail_pane_get_shell_backend; - iface->get_window = mail_pane_get_window; - iface->set_folder = mail_pane_set_folder; - iface->show_search_bar = mail_pane_show_search_bar; + return mail_paned_view_type; } +void +e_mail_paned_view_register_type (GTypeModule *type_module) +{ + static const GTypeInfo type_info = { + sizeof (EMailPanedViewClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) mail_paned_view_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EMailPanedView), + 0, /* n_preallocs */ + (GInstanceInitFunc) mail_paned_view_init, + NULL /* value_table */ + }; + + static const GInterfaceInfo orientable_info = { + (GInterfaceInitFunc) NULL, + (GInterfaceFinalizeFunc) NULL, + NULL /* interface_data */ + }; + + static const GInterfaceInfo reader_info = { + (GInterfaceInitFunc) mail_paned_view_reader_init, + (GInterfaceFinalizeFunc) NULL, + NULL /* interface_data */ + }; + + mail_paned_view_type = g_type_module_register_type ( + type_module, E_MAIL_VIEW_TYPE, + "EMailPanedView", &type_info, 0); + + g_type_module_add_interface ( + type_module, mail_paned_view_type, + GTK_TYPE_ORIENTABLE, &orientable_info); + + g_type_module_add_interface ( + type_module, mail_paned_view_type, + E_TYPE_MAIL_READER, &reader_info); +} + + GtkWidget * e_mail_paned_view_new (EShellContent *content) { g_return_val_if_fail (E_IS_SHELL_CONTENT (content), NULL); return g_object_new ( - E_TYPE_MAIL_PANED_VIEW, + E_MAIL_PANED_VIEW_TYPE, "shell-content", content, NULL); } @@ -358,7 +839,7 @@ e_mail_paned_view_get_searchbar (EMailPanedView *view) g_return_val_if_fail ( E_IS_MAIL_PANED_VIEW (view), NULL); - shell_content = E_PANED_VIEW (view)->content; + shell_content = E_MAIL_VIEW (view)->content; shell_view = e_shell_content_get_shell_view (shell_content); widget = e_shell_view_get_searchbar (shell_view); @@ -395,7 +876,7 @@ e_mail_paned_view_get_view_instance (EMailPanedView *view) } void -e_mail_paned_view_set_search_strings (EmailPanedView *view, +e_mail_paned_view_set_search_strings (EMailPanedView *view, GSList *search_strings) { ESearchBar *search_bar; @@ -435,7 +916,7 @@ mail_paned_display_view_cb (EMailPanedView *view, } void -e_mail_shell_content_update_view_instance (EMailPanedView *view) +e_mail_paned_view_update_view_instance (EMailPanedView *view) { EMailReader *reader; EShell *shell; @@ -454,8 +935,6 @@ e_mail_shell_content_update_view_instance (EMailPanedView *view) const gchar *folder_uri; gchar *view_id; - g_return_if_fail (E_IS_MAIL_SHELL_CONTENT (mail_shell_content)); - shell_content = E_MAIL_VIEW(view)->content; shell_view = e_shell_content_get_shell_view (shell_content); shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view); |