aboutsummaryrefslogtreecommitdiffstats
path: root/mail/em-folder-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'mail/em-folder-tree.c')
-rw-r--r--mail/em-folder-tree.c112
1 files changed, 64 insertions, 48 deletions
diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c
index cb9de25d7e..2e368a14d3 100644
--- a/mail/em-folder-tree.c
+++ b/mail/em-folder-tree.c
@@ -34,12 +34,15 @@
#include <fcntl.h>
#include <errno.h>
+#include <libxml/tree.h>
+
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <camel/camel-session.h>
#include <camel/camel-store.h>
#include <camel/camel-folder.h>
+#include <camel/camel-vee-store.h>
#include <camel/camel-vtrash-folder.h>
#include <camel/camel-stream-mem.h>
#include <camel/camel-file-utils.h>
@@ -80,6 +83,7 @@ struct _EMFolderTreePrivate {
guint save_state_id;
guint loading_row_id;
+ guint loaded_row_id;
GtkTreeRowReference *drag_row;
};
@@ -374,6 +378,11 @@ em_folder_tree_destroy (GtkObject *obj)
priv->loading_row_id = 0;
}
+ if (priv->loaded_row_id != 0) {
+ g_signal_handler_disconnect (priv->model, priv->loaded_row_id);
+ priv->loaded_row_id = 0;
+ }
+
if (priv->save_state_id != 0) {
g_source_remove (priv->save_state_id);
emft_save_state (emft);
@@ -458,75 +467,72 @@ em_folder_tree_new (void)
return (GtkWidget *) emft;
}
-struct _gsbn {
- struct _EMFolderTreeModelStoreInfo *si;
- const char *name;
-};
-
-static void
-emft_get_store_by_name (CamelStore *store, struct _EMFolderTreeModelStoreInfo *si, struct _gsbn *gsbn)
-{
- if (!strcmp (si->display_name, gsbn->name))
- gsbn->si = si;
-}
-
static void
-emft_expand_node (const char *key, gpointer value, EMFolderTree *emft)
+emft_expand_node (EMFolderTreeModel *model, const char *key, EMFolderTree *emft)
{
struct _EMFolderTreePrivate *priv = emft->priv;
struct _EMFolderTreeModelStoreInfo *si;
+ extern CamelStore *vfolder_store;
GtkTreeRowReference *row;
GtkTreePath *path;
EAccount *account;
+ CamelStore *store;
const char *p;
- char *id;
+ char *uid;
+ size_t n;
- if (!(p = strchr (key, ':')))
- return;
+ if (!(p = strchr (key, '/')))
+ n = strlen (key);
+ else
+ n = (p - key);
+
+ uid = g_alloca (n + 1);
+ memcpy (uid, key, n);
+ uid[n] = '\0';
- id = g_strndup (key, p - key);
- if ((account = mail_config_get_account_by_uid (id)) && account->enabled) {
+ if ((account = mail_config_get_account_by_uid (uid)) && account->enabled) {
CamelException ex;
- CamelStore *store;
camel_exception_init (&ex);
store = (CamelStore *) camel_session_get_service (session, account->source->url, CAMEL_PROVIDER_STORE, &ex);
camel_exception_clear (&ex);
- if (store == NULL || !(si = g_hash_table_lookup (priv->model->store_hash, store))) {
- if (store)
- camel_object_unref (store);
- g_free (id);
+ if (store == NULL)
+ return;
+ } else if (!strcmp (uid, "vfolder")) {
+ if (!(store = vfolder_store))
return;
- }
- } else {
- struct _gsbn gsbn;
-
- gsbn.si = NULL;
- gsbn.name = id;
- g_hash_table_foreach (priv->model->store_hash, (GHFunc) emft_get_store_by_name, &gsbn);
- if (!(si = gsbn.si)) {
- g_free (id);
+ camel_object_ref (store);
+ } else if (!strcmp (uid, "local")) {
+ if (!(store = mail_component_peek_local_store (NULL)))
return;
- }
+
+ camel_object_ref (store);
+ } else {
+ return;
+ }
+
+ if (!(si = g_hash_table_lookup (priv->model->store_hash, store))) {
+ camel_object_unref (store);
+ return;
}
- g_free (id);
+ camel_object_unref (store);
- p++;
- if (!strcmp (p, "/"))
+ if (p != NULL) {
+ if (!(row = g_hash_table_lookup (si->path_hash, p)))
+ return;
+ } else
row = si->row;
- else if (!(row = g_hash_table_lookup (si->path_hash, p)))
- return;
path = gtk_tree_row_reference_get_path (row);
- gtk_tree_view_expand_to_path (priv->treeview, path);
+ gtk_tree_view_expand_row (priv->treeview, path, FALSE);
gtk_tree_path_free (path);
}
static void
-emft_loading_row_cb (EMFolderTreeModel *model, GtkTreePath *tree_path, GtkTreeIter *iter, EMFolderTree *emft)
+emft_maybe_expand_row (EMFolderTreeModel *model, GtkTreePath *tree_path, GtkTreeIter *iter, EMFolderTree *emft)
{
struct _EMFolderTreeModelStoreInfo *si;
CamelStore *store;
@@ -540,13 +546,19 @@ emft_loading_row_cb (EMFolderTreeModel *model, GtkTreePath *tree_path, GtkTreeIt
si = g_hash_table_lookup (model->store_hash, store);
if ((account = mail_config_get_account_by_name (si->display_name))) {
- key = g_strdup_printf ("%s:%s", account->uid, path);
+ key = g_strdup_printf ("%s%s", account->uid, path);
+ } else if (CAMEL_IS_VEE_STORE (store)) {
+ /* vfolder store */
+ key = g_strdup_printf ("vfolder%s", path);
} else {
- key = g_strdup_printf ("%s:%s", si->display_name, path);
+ /* local store */
+ key = g_strdup_printf ("local%s", path);
}
- if (em_folder_tree_model_get_expanded (model, key))
+ if (em_folder_tree_model_get_expanded (model, key)) {
gtk_tree_view_expand_to_path (emft->priv->treeview, tree_path);
+ gtk_tree_view_expand_row (emft->priv->treeview, tree_path, FALSE);
+ }
g_free (key);
}
@@ -560,10 +572,10 @@ em_folder_tree_new_with_model (EMFolderTreeModel *model)
em_folder_tree_construct (emft, model);
g_object_ref (model);
- /* FIXME: this sucks... */
- g_hash_table_foreach (model->expanded, (GHFunc) emft_expand_node, emft);
+ em_folder_tree_model_expand_foreach (model, emft_expand_node, emft);
- emft->priv->loading_row_id = g_signal_connect (model, "loading-row", G_CALLBACK (emft_loading_row_cb), emft);
+ emft->priv->loading_row_id = g_signal_connect (model, "loading-row", G_CALLBACK (emft_maybe_expand_row), emft);
+ emft->priv->loaded_row_id = g_signal_connect (model, "loaded-row", G_CALLBACK (emft_maybe_expand_row), emft);
return (GtkWidget *) emft;
}
@@ -1562,9 +1574,13 @@ emft_update_model_expanded_state (struct _EMFolderTreePrivate *priv, GtkTreeIter
si = g_hash_table_lookup (priv->model->store_hash, store);
if ((account = mail_config_get_account_by_name (si->display_name))) {
- key = g_strdup_printf ("%s:%s", account->uid, path);
+ key = g_strdup_printf ("%s%s", account->uid, path);
+ } else if (CAMEL_IS_VEE_STORE (store)) {
+ /* vfolder store */
+ key = g_strdup_printf ("vfolder%s", path);
} else {
- key = g_strdup_printf ("%s:%s", si->display_name, path);
+ /* local store */
+ key = g_strdup_printf ("local%s", path);
}
em_folder_tree_model_set_expanded (priv->model, key, expanded);