diff options
author | Milan Crha <mcrha@redhat.com> | 2010-01-07 23:46:14 +0800 |
---|---|---|
committer | Milan Crha <mcrha@redhat.com> | 2010-01-07 23:46:14 +0800 |
commit | 5accac136eb35405cbb8069e0f12191391c58a1a (patch) | |
tree | 57a77881b2756be22daf81fee29af372356533f8 | |
parent | 84d1cc73e2b9765b02b361a45c50b8bab25d4436 (diff) | |
download | gsoc2013-evolution-5accac136eb35405cbb8069e0f12191391c58a1a.tar.gz gsoc2013-evolution-5accac136eb35405cbb8069e0f12191391c58a1a.tar.zst gsoc2013-evolution-5accac136eb35405cbb8069e0f12191391c58a1a.zip |
Bug #604994 - Folder state not preserved in Copy/Move Folder dialog
-rw-r--r-- | mail/e-mail-reader.c | 2 | ||||
-rw-r--r-- | mail/e-mail-sidebar.c | 99 | ||||
-rw-r--r-- | mail/em-composer-utils.c | 1 | ||||
-rw-r--r-- | mail/em-folder-selection-button.c | 1 | ||||
-rw-r--r-- | mail/em-folder-tree.c | 140 | ||||
-rw-r--r-- | mail/em-folder-tree.h | 4 | ||||
-rw-r--r-- | mail/em-folder-utils.c | 2 | ||||
-rw-r--r-- | mail/em-utils.c | 35 | ||||
-rw-r--r-- | mail/em-utils.h | 3 | ||||
-rw-r--r-- | mail/em-vfolder-rule.c | 1 |
10 files changed, 191 insertions, 97 deletions
diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c index 74b4f1a427..5689a96ce0 100644 --- a/mail/e-mail-reader.c +++ b/mail/e-mail-reader.c @@ -181,6 +181,7 @@ action_mail_copy_cb (GtkAction *action, uids = e_mail_reader_get_selected_uids (reader); folder_tree = em_folder_tree_new (); + emu_restore_folder_tree_state (EM_FOLDER_TREE (folder_tree)); em_folder_tree_set_excluded ( EM_FOLDER_TREE (folder_tree), @@ -558,6 +559,7 @@ action_mail_move_cb (GtkAction *action, window = e_mail_reader_get_window (reader); folder_tree = em_folder_tree_new (); + emu_restore_folder_tree_state (EM_FOLDER_TREE (folder_tree)); em_folder_tree_set_excluded ( EM_FOLDER_TREE (folder_tree), diff --git a/mail/e-mail-sidebar.c b/mail/e-mail-sidebar.c index 95379e51a5..bde8c010c6 100644 --- a/mail/e-mail-sidebar.c +++ b/mail/e-mail-sidebar.c @@ -31,8 +31,6 @@ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_MAIL_SIDEBAR, EMailSidebarPrivate)) -#define STATE_KEY_EXPANDED "Expanded" - struct _EMailSidebarPrivate { GKeyFile *key_file; /* not owned */ }; @@ -55,13 +53,8 @@ mail_sidebar_restore_state (EMailSidebar *sidebar) { EMFolderTree *folder_tree; GtkTreeModel *tree_model; - GtkTreeView *tree_view; - GtkTreeIter iter; GKeyFile *key_file; - gboolean valid; gchar *selected; - gchar **groups; - gint ii; key_file = e_mail_sidebar_get_key_file (sidebar); @@ -70,9 +63,7 @@ mail_sidebar_restore_state (EMailSidebar *sidebar) return; folder_tree = EM_FOLDER_TREE (sidebar); - - tree_view = GTK_TREE_VIEW (sidebar); - tree_model = gtk_tree_view_get_model (tree_view); + tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (sidebar)); /* Restore selected folder. */ @@ -83,93 +74,7 @@ mail_sidebar_restore_state (EMailSidebar *sidebar) g_free (selected); } - /* Set the initial folder tree expanded state in two stages: - * - * 1) Iterate over the "Store" and "Folder" state file groups - * and apply the "Expanded" keys where possible. - * - * 2) Iterate over the top-level nodes in the folder tree - * (these are all stores) and expand those that have no - * corresponding "Expanded" key in the state file. This - * ensures that new stores are expanded by default. - */ - - /* Stage 1 */ - - /* Collapse all so we have a clean slate. */ - gtk_tree_view_collapse_all (tree_view); - - groups = g_key_file_get_groups (key_file, NULL); - - for (ii = 0; groups[ii] != NULL; ii++) { - GtkTreeRowReference *reference; - GtkTreePath *path; - GtkTreeIter iter; - const gchar *group_name = groups[ii]; - const gchar *key = STATE_KEY_EXPANDED; - const gchar *uri; - gboolean expanded; - - if (g_str_has_prefix (group_name, "Store ")) { - uri = group_name + 6; - expanded = TRUE; - } else if (g_str_has_prefix (group_name, "Folder ")) { - uri = group_name + 7; - expanded = FALSE; - } else - continue; - - if (g_key_file_has_key (key_file, group_name, key, NULL)) - expanded = g_key_file_get_boolean ( - key_file, group_name, key, NULL); - - if (!expanded) - continue; - - reference = em_folder_tree_model_lookup_uri ( - EM_FOLDER_TREE_MODEL (tree_model), uri); - if (reference == NULL) - continue; - - path = gtk_tree_row_reference_get_path (reference); - gtk_tree_model_get_iter (tree_model, &iter, path); - gtk_tree_view_expand_row (tree_view, path, FALSE); - gtk_tree_path_free (path); - } - - g_strfreev (groups); - - /* Stage 2 */ - - valid = gtk_tree_model_get_iter_first (tree_model, &iter); - - while (valid) { - const gchar *key = STATE_KEY_EXPANDED; - gchar *group_name; - gchar *uri; - - gtk_tree_model_get ( - tree_model, &iter, COL_STRING_URI, &uri, -1); - - if (uri == NULL) - goto next; - - group_name = g_strdup_printf ("Store %s", uri); - - if (!g_key_file_has_key (key_file, group_name, key, NULL)) { - GtkTreePath *path; - - path = gtk_tree_model_get_path (tree_model, &iter); - gtk_tree_view_expand_row (tree_view, path, FALSE); - gtk_tree_path_free (path); - } - - g_free (group_name); - g_free (uri); - - next: - valid = gtk_tree_model_iter_next (tree_model, &iter); - } + em_folder_tree_restore_state (folder_tree, key_file); } static void diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c index 1e2ceb01c4..f537ceddb2 100644 --- a/mail/em-composer-utils.c +++ b/mail/em-composer-utils.c @@ -2309,6 +2309,7 @@ post_header_clicked_cb (EComposerPostHeader *header, GList *list; folder_tree = em_folder_tree_new (); + emu_restore_folder_tree_state (EM_FOLDER_TREE (folder_tree)); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_tree)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); diff --git a/mail/em-folder-selection-button.c b/mail/em-folder-selection-button.c index d3d44e5c23..48737a122a 100644 --- a/mail/em-folder-selection-button.c +++ b/mail/em-folder-selection-button.c @@ -216,6 +216,7 @@ folder_selection_button_clicked (GtkButton *button) parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; emft = (EMFolderTree *) em_folder_tree_new (); + emu_restore_folder_tree_state (emft); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (emft)); if (priv->multiple_select) diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c index c439961572..0709f28fed 100644 --- a/mail/em-folder-tree.c +++ b/mail/em-folder-tree.c @@ -2586,3 +2586,143 @@ em_folder_tree_set_skip_double_click (EMFolderTree *folder_tree, gboolean skip) { folder_tree->priv->skip_double_click = skip; } + +/* stores come first, then by uri */ +static gint +sort_by_store_and_uri (gconstpointer name1, gconstpointer name2) +{ + const gchar *n1 = name1, *n2 = name2; + gboolean is_store1, is_store2; + + if (n1 == NULL || n2 == NULL) { + if (n1 == n2) + return 0; + else + return n1 ? -1 : 1; + } + + is_store1 = g_str_has_prefix (n1, "Store "); + is_store2 = g_str_has_prefix (n2, "Store "); + + if ((is_store1 || is_store2) && (!is_store1 || !is_store2)) { + return is_store1 ? -1 : 1; + } + + return strcmp (n1, n2); +} + +/* restores state of a tree (collapsed/expanded) as stores in the given key_file */ +void +em_folder_tree_restore_state (EMFolderTree *folder_tree, GKeyFile *key_file) +{ + GtkTreeModel *tree_model; + GtkTreeView *tree_view; + GtkTreeIter iter; + gboolean valid; + gchar **groups_arr; + GSList *groups, *group; + gint ii; + + /* Make sure we have a key file to restore state from. */ + if (key_file == NULL) + return; + + tree_view = GTK_TREE_VIEW (folder_tree); + tree_model = gtk_tree_view_get_model (tree_view); + + /* Set the initial folder tree expanded state in two stages: + * + * 1) Iterate over the "Store" and "Folder" state file groups + * and apply the "Expanded" keys where possible. + * + * 2) Iterate over the top-level nodes in the folder tree + * (these are all stores) and expand those that have no + * corresponding "Expanded" key in the state file. This + * ensures that new stores are expanded by default. + */ + + /* Stage 1 */ + + /* Collapse all so we have a clean slate. */ + gtk_tree_view_collapse_all (tree_view); + + groups_arr = g_key_file_get_groups (key_file, NULL); + groups = NULL; + + for (ii = 0; groups_arr[ii] != NULL; ii++) { + groups = g_slist_prepend (groups, groups_arr [ii]); + } + + groups = g_slist_sort (groups, sort_by_store_and_uri); + + for (group = groups; group != NULL; group = group->next) { + GtkTreeRowReference *reference; + GtkTreePath *path; + GtkTreeIter iter; + const gchar *group_name = group->data; + const gchar *key = STATE_KEY_EXPANDED; + const gchar *uri; + gboolean expanded; + + if (g_str_has_prefix (group_name, "Store ")) { + uri = group_name + 6; + expanded = TRUE; + } else if (g_str_has_prefix (group_name, "Folder ")) { + uri = group_name + 7; + expanded = FALSE; + } else + continue; + + if (g_key_file_has_key (key_file, group_name, key, NULL)) + expanded = g_key_file_get_boolean ( + key_file, group_name, key, NULL); + + if (!expanded) + continue; + + reference = em_folder_tree_model_lookup_uri ( + EM_FOLDER_TREE_MODEL (tree_model), uri); + if (reference == NULL) + continue; + + path = gtk_tree_row_reference_get_path (reference); + gtk_tree_model_get_iter (tree_model, &iter, path); + gtk_tree_view_expand_row (tree_view, path, FALSE); + gtk_tree_path_free (path); + } + + g_slist_free (groups); + g_strfreev (groups_arr); + + /* Stage 2 */ + + valid = gtk_tree_model_get_iter_first (tree_model, &iter); + + while (valid) { + const gchar *key = STATE_KEY_EXPANDED; + gchar *group_name; + gchar *uri; + + gtk_tree_model_get ( + tree_model, &iter, COL_STRING_URI, &uri, -1); + + if (uri == NULL) + goto next; + + group_name = g_strdup_printf ("Store %s", uri); + + if (!g_key_file_has_key (key_file, group_name, key, NULL)) { + GtkTreePath *path; + + path = gtk_tree_model_get_path (tree_model, &iter); + gtk_tree_view_expand_row (tree_view, path, FALSE); + gtk_tree_path_free (path); + } + + g_free (group_name); + g_free (uri); + + next: + valid = gtk_tree_model_iter_next (tree_model, &iter); + } +} diff --git a/mail/em-folder-tree.h b/mail/em-folder-tree.h index 02730cb09d..a5722e178e 100644 --- a/mail/em-folder-tree.h +++ b/mail/em-folder-tree.h @@ -53,6 +53,8 @@ typedef struct _EMFolderTree EMFolderTree; typedef struct _EMFolderTreeClass EMFolderTreeClass; typedef struct _EMFolderTreePrivate EMFolderTreePrivate; +#define STATE_KEY_EXPANDED "Expanded" + /* not sure this api is the best, but its the easiest to implement and will cover what we need */ #define EMFT_EXCLUDE_NOSELECT CAMEL_FOLDER_NOSELECT #define EMFT_EXCLUDE_NOINFERIORS CAMEL_FOLDER_NOINFERIORS @@ -122,6 +124,8 @@ void em_folder_tree_set_skip_double_click (EMFolderTree *folder_tree, gboolean skip); +void em_folder_tree_restore_state (EMFolderTree *folder_tree, + GKeyFile *key_file); G_END_DECLS #endif /* EM_FOLDER_TREE_H */ diff --git a/mail/em-folder-utils.c b/mail/em-folder-utils.c index 2838e829bd..447237f3a4 100644 --- a/mail/em-folder-utils.c +++ b/mail/em-folder-utils.c @@ -374,6 +374,7 @@ em_folder_utils_copy_folder (GtkWindow *parent, /* XXX Do we leak this reference. */ emft = (EMFolderTree *) em_folder_tree_new (); + emu_restore_folder_tree_state (emft); em_folder_tree_set_excluded_func ( emft, emfu_copy_folder_exclude, cfd); @@ -651,6 +652,7 @@ em_folder_utils_create_folder (CamelFolderInfo *folderinfo, EMFolderTree *emft, GtkWidget *dialog; folder_tree = (EMFolderTree *) em_folder_tree_new (); + emu_restore_folder_tree_state (folder_tree); dialog = em_folder_selector_create_new ( parent, folder_tree, 0, diff --git a/mail/em-utils.c b/mail/em-utils.c index 63d323430f..eab434dfaf 100644 --- a/mail/em-utils.c +++ b/mail/em-utils.c @@ -2210,3 +2210,38 @@ em_utils_guess_account (CamelMimeMessage *message, CamelFolder *folder) return account; } + +void +emu_restore_folder_tree_state (EMFolderTree *folder_tree) +{ + EShell *shell; + EShellBackend *backend; + GKeyFile *key_file; + const gchar *config_dir; + gchar *filename; + GError *error = NULL; + + g_return_if_fail (folder_tree != NULL); + g_return_if_fail (EM_IS_FOLDER_TREE (folder_tree)); + + shell = e_shell_get_default (); + backend = e_shell_get_backend_by_name (shell, "mail"); + g_return_if_fail (backend != NULL); + + config_dir = e_shell_backend_get_config_dir (backend); + g_return_if_fail (config_dir != NULL); + + filename = g_build_filename (config_dir, "state", NULL); + + key_file = g_key_file_new (); + g_key_file_load_from_file (key_file, filename, 0, &error); + g_free (filename); + + if (error) { + g_error_free (error); + } else { + em_folder_tree_restore_state (folder_tree, key_file); + } + + g_key_file_free (key_file); +} diff --git a/mail/em-utils.h b/mail/em-utils.h index 2293dfa283..4e3b95ef11 100644 --- a/mail/em-utils.h +++ b/mail/em-utils.h @@ -33,6 +33,7 @@ #include <camel/camel-stream.h> #include <mail/e-mail-reader.h> +#include <mail/em-folder-tree.h> G_BEGIN_DECLS @@ -109,6 +110,8 @@ void emu_remove_from_mail_cache (const GSList *addresses); void emu_remove_from_mail_cache_1 (const gchar *address); void emu_free_mail_cache (void); +void emu_restore_folder_tree_state (EMFolderTree *folder_tree); + G_END_DECLS #endif /* __EM_UTILS_H__ */ diff --git a/mail/em-vfolder-rule.c b/mail/em-vfolder-rule.c index b094cced75..4932470609 100644 --- a/mail/em-vfolder-rule.c +++ b/mail/em-vfolder-rule.c @@ -514,6 +514,7 @@ source_add(GtkWidget *widget, struct _source_data *data) parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; emft =(EMFolderTree *) em_folder_tree_new (); + emu_restore_folder_tree_state (emft); em_folder_tree_set_excluded (emft, EMFT_EXCLUDE_NOSELECT); dialog = em_folder_selector_new ( |