aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2010-01-07 23:46:14 +0800
committerMilan Crha <mcrha@redhat.com>2010-01-07 23:46:14 +0800
commit5accac136eb35405cbb8069e0f12191391c58a1a (patch)
tree57a77881b2756be22daf81fee29af372356533f8
parent84d1cc73e2b9765b02b361a45c50b8bab25d4436 (diff)
downloadgsoc2013-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.c2
-rw-r--r--mail/e-mail-sidebar.c99
-rw-r--r--mail/em-composer-utils.c1
-rw-r--r--mail/em-folder-selection-button.c1
-rw-r--r--mail/em-folder-tree.c140
-rw-r--r--mail/em-folder-tree.h4
-rw-r--r--mail/em-folder-utils.c2
-rw-r--r--mail/em-utils.c35
-rw-r--r--mail/em-utils.h3
-rw-r--r--mail/em-vfolder-rule.c1
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 (