[evolution] I#806 - Mail: Preserve folder tree expand state in a new window
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] I#806 - Mail: Preserve folder tree expand state in a new window
- Date: Wed, 26 Feb 2020 14:48:17 +0000 (UTC)
commit c4d53c3ce2ae9a5c33b6f4ec18d5361fa171800d
Author: Milan Crha <mcrha redhat com>
Date: Wed Feb 26 15:45:34 2020 +0100
I#806 - Mail: Preserve folder tree expand state in a new window
Closes https://gitlab.gnome.org/GNOME/evolution/issues/806
src/mail/e-mail-sidebar.c | 21 ++++++--
src/modules/mail/e-mail-shell-view.c | 100 +++++++++++++++++++++++++++++++++++
src/shell/e-shell-view.c | 20 ++++---
src/shell/e-shell-view.h | 2 +
src/shell/e-shell-window-actions.c | 6 +++
5 files changed, 140 insertions(+), 9 deletions(-)
---
diff --git a/src/mail/e-mail-sidebar.c b/src/mail/e-mail-sidebar.c
index 92ee867457..ad0aafe26a 100644
--- a/src/mail/e-mail-sidebar.c
+++ b/src/mail/e-mail-sidebar.c
@@ -35,6 +35,7 @@ struct _EMailSidebarPrivate {
GKeyFile *key_file; /* not owned */
GtkTreeModel *model;
GtkTreeSelection *selection;
+ gboolean restoring_state;
};
enum {
@@ -71,14 +72,17 @@ mail_sidebar_restore_state (EMailSidebar *sidebar)
/* Restore selected folder. */
- selected = g_key_file_get_string (
- key_file, "Folder Tree", "Selected", NULL);
+ sidebar->priv->restoring_state = TRUE;
+
+ em_folder_tree_restore_state (folder_tree, key_file);
+
+ selected = g_key_file_get_string (key_file, "Folder Tree", "Selected", NULL);
if (selected != NULL) {
em_folder_tree_set_selected (folder_tree, selected, FALSE);
g_free (selected);
}
- em_folder_tree_restore_state (folder_tree, key_file);
+ sidebar->priv->restoring_state = FALSE;
}
static void
@@ -150,6 +154,9 @@ mail_sidebar_selection_changed_cb (GtkTreeSelection *selection,
GKeyFile *key_file;
gchar *uri = NULL;
+ if (sidebar->priv->restoring_state || !gtk_widget_get_realized (GTK_WIDGET (sidebar)))
+ return;
+
key_file = e_mail_sidebar_get_key_file (sidebar);
/* Make sure we have a key file to record state changes. */
@@ -300,6 +307,10 @@ mail_sidebar_row_expanded (GtkTreeView *tree_view,
tree_view_class->row_expanded (tree_view, unused, path);
sidebar = E_MAIL_SIDEBAR (tree_view);
+
+ if (sidebar->priv->restoring_state)
+ return;
+
key_file = e_mail_sidebar_get_key_file (sidebar);
/* Make sure we have a key file to record state changes. */
@@ -369,6 +380,10 @@ mail_sidebar_row_collapsed (GtkTreeView *tree_view,
gchar *group_name;
sidebar = E_MAIL_SIDEBAR (tree_view);
+
+ if (sidebar->priv->restoring_state)
+ return;
+
key_file = e_mail_sidebar_get_key_file (sidebar);
/* Make sure we have a key file to record state changes. */
diff --git a/src/modules/mail/e-mail-shell-view.c b/src/modules/mail/e-mail-shell-view.c
index 264cb2d015..4274751321 100644
--- a/src/modules/mail/e-mail-shell-view.c
+++ b/src/modules/mail/e-mail-shell-view.c
@@ -337,6 +337,105 @@ mail_shell_view_show_search_results_folder (EMailShellView *mail_shell_view,
message_list_thaw (MESSAGE_LIST (message_list));
}
+static void
+e_mail_shell_view_cleanup_state_key_file (EShellView *shell_view)
+{
+ EShellBackend *shell_backend;
+ EMailSession *mail_session;
+ CamelSession *session;
+ GKeyFile *key_file;
+ gchar **groups;
+ gboolean changed = FALSE;
+ gint ii;
+
+ g_return_if_fail (E_IS_MAIL_SHELL_VIEW (shell_view));
+
+ key_file = e_shell_view_get_state_key_file (shell_view);
+ if (!key_file)
+ return;
+
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ mail_session = e_mail_backend_get_session (E_MAIL_BACKEND (shell_backend));
+
+ if (!mail_session)
+ return;
+
+ session = CAMEL_SESSION (mail_session);
+
+ groups = g_key_file_get_groups (key_file, NULL);
+
+ if (!groups)
+ return;
+
+ for (ii = 0; groups[ii]; ii++) {
+ const gchar *group_name = groups[ii];
+
+ if (g_str_has_prefix (group_name, "Store ")) {
+ CamelService *service;
+ const gchar *uid = group_name + 6;
+
+ service = camel_session_ref_service (session, uid);
+
+ if (CAMEL_IS_STORE (service)) {
+ g_object_unref (service);
+ } else {
+ changed = TRUE;
+ g_key_file_remove_group (key_file, group_name, NULL);
+ }
+ } else if (g_str_has_prefix (group_name, "Folder ")) {
+ CamelStore *store = NULL;
+ gchar *folder_name = NULL;
+ const gchar *uri = group_name + 7;
+
+ if (e_mail_folder_uri_parse (session, uri, &store, &folder_name, NULL)) {
+ if (!g_str_has_prefix (uri, "folder:")) {
+ gchar *new_style_uri;
+
+ new_style_uri = e_mail_folder_uri_build (store, folder_name);
+ if (new_style_uri) {
+ if (!g_key_file_has_group (key_file, new_style_uri)) {
+ gchar **keys;
+ gint jj;
+
+ keys = g_key_file_get_keys (key_file, group_name,
NULL, NULL);
+
+ for (jj = 0; keys && keys[jj]; jj++) {
+ const gchar *key = keys[jj];
+ gchar *value;
+
+ value = g_key_file_get_value (key_file,
group_name, key, NULL);
+
+ if (value) {
+ g_key_file_set_value (key_file,
group_name, key, value);
+ g_free (value);
+ }
+ }
+
+ g_strfreev (keys);
+ }
+
+ changed = TRUE;
+ g_key_file_remove_group (key_file, group_name, NULL);
+ }
+ }
+
+ g_clear_object (&store);
+ g_free (folder_name);
+
+ /* One non-Folder section is named "Folder Tree", thus avoid erasing it and others
not looking like URI */
+ } else if (strstr (group_name, ":/")) {
+ changed = TRUE;
+ g_key_file_remove_group (key_file, group_name, NULL);
+ }
+ }
+ }
+
+ g_strfreev (groups);
+
+ if (changed)
+ e_shell_view_set_state_dirty (shell_view);
+}
+
static void
mail_shell_view_set_vfolder_allow_expunge (EMailShellView *mail_shell_view,
gboolean value)
@@ -419,6 +518,7 @@ mail_shell_view_constructed (GObject *object)
G_OBJECT_CLASS (e_mail_shell_view_parent_class)->constructed (object);
e_mail_shell_view_private_constructed (E_MAIL_SHELL_VIEW (object));
+ e_mail_shell_view_cleanup_state_key_file (E_SHELL_VIEW (object));
}
static void
diff --git a/src/shell/e-shell-view.c b/src/shell/e-shell-view.c
index be5530ddc7..9975da9c7b 100644
--- a/src/shell/e-shell-view.c
+++ b/src/shell/e-shell-view.c
@@ -328,6 +328,19 @@ shell_view_state_timeout_cb (gpointer user_data)
return FALSE;
}
+void
+e_shell_view_save_state_immediately (EShellView *shell_view)
+{
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+
+ if (shell_view->priv->state_save_timeout_id > 0) {
+ g_source_remove (shell_view->priv->state_save_timeout_id);
+ shell_view->priv->state_save_timeout_id = 0;
+ if (!shell_view->priv->state_save_activity)
+ shell_view_save_state (shell_view, TRUE);
+ }
+}
+
static void
shell_view_emit_toggled (EShellView *shell_view)
{
@@ -517,12 +530,7 @@ shell_view_dispose (GObject *object)
priv = E_SHELL_VIEW_GET_PRIVATE (object);
/* Expedite any pending state saves. */
- if (priv->state_save_timeout_id > 0) {
- g_source_remove (priv->state_save_timeout_id);
- priv->state_save_timeout_id = 0;
- if (priv->state_save_activity == NULL)
- shell_view_save_state (E_SHELL_VIEW (object), TRUE);
- }
+ e_shell_view_save_state_immediately (E_SHELL_VIEW (object));
if (priv->update_actions_idle_id > 0) {
g_source_remove (priv->update_actions_idle_id);
diff --git a/src/shell/e-shell-view.h b/src/shell/e-shell-view.h
index cdbebc4d1b..82d2970b92 100644
--- a/src/shell/e-shell-view.h
+++ b/src/shell/e-shell-view.h
@@ -222,6 +222,8 @@ EShellTaskbar * e_shell_view_get_shell_taskbar (EShellView *shell_view);
EShellWindow * e_shell_view_get_shell_window (EShellView *shell_view);
GKeyFile * e_shell_view_get_state_key_file (EShellView *shell_view);
void e_shell_view_set_state_dirty (EShellView *shell_view);
+void e_shell_view_save_state_immediately
+ (EShellView *shell_view);
void e_shell_view_clear_search (EShellView *shell_view);
void e_shell_view_custom_search (EShellView *shell_view,
EFilterRule *custom_rule);
diff --git a/src/shell/e-shell-window-actions.c b/src/shell/e-shell-window-actions.c
index f8c565f1cb..db7c078f66 100644
--- a/src/shell/e-shell-window-actions.c
+++ b/src/shell/e-shell-window-actions.c
@@ -298,11 +298,17 @@ action_new_window_cb (GtkAction *action,
EShellWindow *shell_window)
{
EShell *shell;
+ EShellView *shell_view;
const gchar *view_name;
shell = e_shell_window_get_shell (shell_window);
view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+
+ if (shell_view)
+ e_shell_view_save_state_immediately (shell_view);
+
e_shell_create_shell_window (shell, view_name);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]