aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@ximian.com>2004-03-17 06:54:55 +0800
committerJeffrey Stedfast <fejj@src.gnome.org>2004-03-17 06:54:55 +0800
commitb036a0df45473a69635b72f71341bc5d4f3deb5e (patch)
treec6c161541287b46cfdd74b513f4dcdb4aa453c91
parentadba504c23874aa85a3ab8e72c9c8dd49aed79ec (diff)
downloadgsoc2013-evolution-b036a0df45473a69635b72f71341bc5d4f3deb5e.tar
gsoc2013-evolution-b036a0df45473a69635b72f71341bc5d4f3deb5e.tar.gz
gsoc2013-evolution-b036a0df45473a69635b72f71341bc5d4f3deb5e.tar.bz2
gsoc2013-evolution-b036a0df45473a69635b72f71341bc5d4f3deb5e.tar.lz
gsoc2013-evolution-b036a0df45473a69635b72f71341bc5d4f3deb5e.tar.xz
gsoc2013-evolution-b036a0df45473a69635b72f71341bc5d4f3deb5e.tar.zst
gsoc2013-evolution-b036a0df45473a69635b72f71341bc5d4f3deb5e.zip
Fix for bug #55358.
2004-03-16 Jeffrey Stedfast <fejj@ximian.com> Fix for bug #55358. * em-folder-tree.c (emft_expand_node): Changed to be the callback function for em_folder_tree_model_expand_foreach(). (emft_maybe_expand_row): Renamed from emft_loading_row_cb(). We now handle both "loading-row" an "loaded-row" signals. Also updated for slight change in key generation. (em_folder_tree_new_with_model): Connect to the "loaded-row" signal. (emft_update_model_expanded_state): Updated for slight change in key generation. * em-folder-tree-model.c (em_folder_tree_model_add_store): Emit the "loaded-row" signal for the newly added store. (em_folder_tree_model_set_folder_info): Emit "loaded-row" for the row we've just set the info on (but only after we've added a child node if there is one, so the signal handler can expand the newly added row if appropriate). (em_folder_tree_model_class_init): Setup the "loaded-row" signal. (em_folder_tree_model_finalize): The tree-state is now an xml file and not a binary file, so change the expanded free func. (em_folder_tree_model_load_state): Load the expand-state xml file. If one doesn't exist, setup some defaults. (em_folder_tree_model_get_expanded): Scan the XML tree for the node. (em_folder_tree_model_set_expanded): Same. (em_folder_tree_model_save_expanded): Save the expand-state xml tree to disk. (em_folder_tree_model_expand_foreach): New function to iterate over all xml nodes and call the callback if the expand state is "true". svn path=/trunk/; revision=25094
-rw-r--r--mail/ChangeLog34
-rw-r--r--mail/em-folder-tree-model.c299
-rw-r--r--mail/em-folder-tree-model.h13
-rw-r--r--mail/em-folder-tree.c112
-rw-r--r--mail/mail-component.c1
5 files changed, 320 insertions, 139 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 6c7795221d..c87cb09a45 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,5 +1,39 @@
2004-03-16 Jeffrey Stedfast <fejj@ximian.com>
+ Fix for bug #55358.
+
+ * em-folder-tree.c (emft_expand_node): Changed to be the callback
+ function for em_folder_tree_model_expand_foreach().
+ (emft_maybe_expand_row): Renamed from emft_loading_row_cb(). We
+ now handle both "loading-row" an "loaded-row" signals. Also
+ updated for slight change in key generation.
+ (em_folder_tree_new_with_model): Connect to the "loaded-row"
+ signal.
+ (emft_update_model_expanded_state): Updated for slight change in
+ key generation.
+
+ * em-folder-tree-model.c (em_folder_tree_model_add_store): Emit
+ the "loaded-row" signal for the newly added store.
+ (em_folder_tree_model_set_folder_info): Emit "loaded-row" for the
+ row we've just set the info on (but only after we've added a child
+ node if there is one, so the signal handler can expand the newly
+ added row if appropriate).
+ (em_folder_tree_model_class_init): Setup the "loaded-row" signal.
+ (em_folder_tree_model_finalize): The tree-state is now an xml file
+ and not a binary file, so change the expanded free func.
+ (em_folder_tree_model_load_state): Load the expand-state xml
+ file. If one doesn't exist, setup some defaults.
+ (em_folder_tree_model_get_expanded): Scan the XML tree for the
+ node.
+ (em_folder_tree_model_set_expanded): Same.
+ (em_folder_tree_model_save_expanded): Save the expand-state xml
+ tree to disk.
+ (em_folder_tree_model_expand_foreach): New function to iterate
+ over all xml nodes and call the callback if the expand state is
+ "true".
+
+2004-03-16 Jeffrey Stedfast <fejj@ximian.com>
+
* mail-component.c (impl_requestCreateItem): Don't focus the
name_entry widget here.
diff --git a/mail/em-folder-tree-model.c b/mail/em-folder-tree-model.c
index 0f240aa056..4efa1ca7f9 100644
--- a/mail/em-folder-tree-model.c
+++ b/mail/em-folder-tree-model.c
@@ -32,8 +32,12 @@
#include <fcntl.h>
#include <errno.h>
+#include <libxml/parser.h>
+
#include <e-util/e-mktemp.h>
+#include <gal/util/e-xml-utils.h>
+
#include <camel/camel-file-utils.h>
#include "mail-config.h"
@@ -78,6 +82,7 @@ static void account_removed (EAccountList *accounts, EAccount *account, gpointer
enum {
LOADING_ROW,
+ LOADED_ROW,
FOLDER_ADDED,
LAST_SIGNAL
};
@@ -146,11 +151,22 @@ em_folder_tree_model_class_init (EMFolderTreeModelClass *klass)
G_TYPE_POINTER,
G_TYPE_POINTER);
+ signals[LOADED_ROW] =
+ g_signal_new ("loaded-row",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMFolderTreeModelClass, loaded_row),
+ NULL, NULL,
+ em_marshal_VOID__POINTER_POINTER,
+ G_TYPE_NONE, 2,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER);
+
signals[FOLDER_ADDED] =
g_signal_new ("folder-added",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMFolderTreeModelClass, loading_row),
+ G_STRUCT_OFFSET (EMFolderTreeModelClass, folder_added),
NULL, NULL,
em_marshal_VOID__STRING_STRING,
G_TYPE_NONE, 2,
@@ -237,7 +253,6 @@ em_folder_tree_model_init (EMFolderTreeModel *model)
{
model->store_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
model->uri_hash = g_hash_table_new (g_str_hash, g_str_equal);
- model->expanded = g_hash_table_new (g_str_hash, g_str_equal);
gtk_tree_sortable_set_default_sort_func ((GtkTreeSortable *) model, sort_cb, NULL, NULL);
@@ -285,33 +300,25 @@ uri_hash_free (gpointer key, gpointer value, gpointer user_data)
gtk_tree_row_reference_free (value);
}
-static gboolean
-expanded_free (gpointer key, gpointer value, gpointer user_data)
-{
- g_free (key);
- return TRUE;
-}
-
static void
em_folder_tree_model_finalize (GObject *obj)
{
EMFolderTreeModel *model = (EMFolderTreeModel *) obj;
+ g_free (model->filename);
+ if (model->expanded)
+ xmlFreeDoc (model->expanded);
+
g_hash_table_foreach (model->store_hash, store_hash_free, NULL);
g_hash_table_destroy (model->store_hash);
g_hash_table_foreach (model->uri_hash, uri_hash_free, NULL);
g_hash_table_destroy (model->uri_hash);
- g_hash_table_foreach (model->expanded, (GHFunc) expanded_free, NULL);
- g_hash_table_destroy (model->expanded);
-
g_hash_table_destroy (model->account_hash);
g_signal_handler_disconnect (model->accounts, model->account_changed_id);
g_signal_handler_disconnect (model->accounts, model->account_removed_id);
- g_free (model->filename);
-
G_OBJECT_CLASS (parent_class)->finalize (obj);
}
@@ -332,18 +339,27 @@ tree_sortable_iface_init (GtkTreeSortableIface *iface)
static void
em_folder_tree_model_load_state (EMFolderTreeModel *model, const char *filename)
{
- char *node;
- FILE *fp;
+ xmlNodePtr root, node;
+ struct stat st;
- g_hash_table_foreach_remove (model->expanded, expanded_free, NULL);
+ if (model->expanded)
+ xmlFreeDoc (model->expanded);
- if ((fp = fopen (filename, "r")) == NULL)
+ if (stat (filename, &st) == 0 && (model->expanded = xmlParseFile (filename)))
return;
- while (camel_file_util_decode_string (fp, &node) != -1)
- g_hash_table_insert (model->expanded, node, GINT_TO_POINTER (TRUE));
+ /* setup some defaults - expand "Local Folders" and "VFolders" */
+ model->expanded = xmlNewDoc ("1.0");
+ root = xmlNewDocNode (model->expanded, NULL, "tree-state", NULL);
+ xmlDocSetRootElement (model->expanded, root);
+
+ node = xmlNewChild (root, NULL, "node", NULL);
+ xmlSetProp (node, "name", "local");
+ xmlSetProp (node, "expand", "true");
- fclose (fp);
+ node = xmlNewChild (root, NULL, "node", NULL);
+ xmlSetProp (node, "name", "vfolder");
+ xmlSetProp (node, "expand", "true");
}
@@ -359,7 +375,7 @@ em_folder_tree_model_new (const char *evolution_dir)
GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
GTK_SORT_ASCENDING);
- filename = g_build_filename (evolution_dir, "mail", "config", "folder-tree.state", NULL);
+ filename = g_build_filename (evolution_dir, "mail", "config", "folder-tree-expand-state.xml", NULL);
em_folder_tree_model_load_state (model, filename);
model->filename = filename;
@@ -428,17 +444,18 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *ite
GtkTreeIter sub;
gboolean load;
struct _CamelFolder *folder;
-
+ gboolean emitted = FALSE;
+
load = fi->child == NULL && !(fi->flags & (CAMEL_FOLDER_NOCHILDREN | CAMEL_FOLDER_NOINFERIORS));
path = gtk_tree_model_get_path ((GtkTreeModel *) model, iter);
uri_row = gtk_tree_row_reference_new ((GtkTreeModel *) model, path);
path_row = gtk_tree_row_reference_copy (uri_row);
gtk_tree_path_free (path);
-
+
g_hash_table_insert (model->uri_hash, g_strdup (fi->uri), uri_row);
g_hash_table_insert (si->path_hash, g_strdup (fi->path), path_row);
-
+
/* HACK: if we have the folder, and its the outbox folder, we need the total count, not unread */
/* This is duplicated in mail-folder-cache too, should perhaps be functionised */
unread = fi->unread == -1 ? 0 : fi->unread;
@@ -459,15 +476,7 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *ite
COL_BOOL_LOAD_SUBDIRS, load,
-1);
- if (fi->child) {
- fi = fi->child;
-
- do {
- gtk_tree_store_append ((GtkTreeStore *) model, &sub, iter);
- em_folder_tree_model_set_folder_info (model, &sub, si, fi);
- fi = fi->next;
- } while (fi);
- } else if (load) {
+ if (load) {
/* create a placeholder node for our subfolders... */
gtk_tree_store_append ((GtkTreeStore *) model, &sub, iter);
gtk_tree_store_set ((GtkTreeStore *) model, &sub,
@@ -483,6 +492,31 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *ite
path = gtk_tree_model_get_path ((GtkTreeModel *) model, iter);
g_signal_emit (model, signals[LOADING_ROW], 0, path, iter);
gtk_tree_path_free (path);
+ return;
+ }
+
+ if (fi->child) {
+ fi = fi->child;
+
+ do {
+ gtk_tree_store_append ((GtkTreeStore *) model, &sub, iter);
+
+ if (!emitted) {
+ path = gtk_tree_model_get_path ((GtkTreeModel *) model, iter);
+ g_signal_emit (model, signals[LOADED_ROW], 0, path, iter);
+ gtk_tree_path_free (path);
+ emitted = TRUE;
+ }
+
+ em_folder_tree_model_set_folder_info (model, &sub, si, fi);
+ fi = fi->next;
+ } while (fi);
+ }
+
+ if (!emitted) {
+ path = gtk_tree_model_get_path ((GtkTreeModel *) model, iter);
+ g_signal_emit (model, signals[LOADED_ROW], 0, path, iter);
+ gtk_tree_path_free (path);
}
}
@@ -740,7 +774,6 @@ em_folder_tree_model_add_store (EMFolderTreeModel *model, CamelStore *store, con
path = gtk_tree_model_get_path ((GtkTreeModel *) model, &iter);
row = gtk_tree_row_reference_new ((GtkTreeModel *) model, path);
- gtk_tree_path_free (path);
si = g_new (struct _EMFolderTreeModelStoreInfo, 1);
si->display_name = g_strdup (display_name);
@@ -774,6 +807,9 @@ em_folder_tree_model_add_store (EMFolderTreeModel *model, CamelStore *store, con
si->renamed_id = camel_object_hook_event (store, "folder_renamed", CAMEL_CALLBACK (folder_renamed_cb), model);
si->subscribed_id = camel_object_hook_event (store, "folder_subscribed", CAMEL_CALLBACK (folder_subscribed_cb), model);
si->unsubscribed_id = camel_object_hook_event (store, "folder_unsubscribed", CAMEL_CALLBACK (folder_unsubscribed_cb), model);
+
+ g_signal_emit (model, signals[LOADED_ROW], 0, path, &root);
+ gtk_tree_path_free (path);
}
@@ -870,11 +906,64 @@ em_folder_tree_model_remove_store (EMFolderTreeModel *model, CamelStore *store)
}
+static xmlNodePtr
+find_xml_node (xmlNodePtr root, const char *name)
+{
+ xmlNodePtr node;
+ char *nname;
+
+ node = root->children;
+ while (node != NULL) {
+ if (!strcmp (node->name, "node")) {
+ nname = xmlGetProp (node, "name");
+ if (nname && !strcmp (nname, name)) {
+ xmlFree (nname);
+ return node;
+ }
+
+ xmlFree (nname);
+ }
+
+ node = node->next;
+ }
+
+ return node;
+}
+
gboolean
em_folder_tree_model_get_expanded (EMFolderTreeModel *model, const char *key)
{
- if (g_hash_table_lookup (model->expanded, key))
- return TRUE;
+ xmlNodePtr node;
+ const char *name;
+ char *buf, *p;
+
+ node = model->expanded ? model->expanded->children : NULL;
+ if (!node || strcmp (node->name, "tree-state") != 0)
+ return FALSE;
+
+ name = buf = g_alloca (strlen (key) + 1);
+ p = g_stpcpy (buf, key);
+ if (p[-1] == '/')
+ p[-1] = '\0';
+ p = NULL;
+
+ do {
+ if ((p = strchr (name, '/')))
+ *p = '\0';
+
+ if ((node = find_xml_node (node, name))) {
+ gboolean expanded;
+
+ buf = xmlGetProp (node, "expand");
+ expanded = buf && !strcmp (buf, "true");
+ xmlFree (buf);
+
+ if (!expanded || p == NULL)
+ return expanded;
+ }
+
+ name = p ? p + 1 : NULL;
+ } while (name && node);
return FALSE;
}
@@ -883,34 +972,58 @@ em_folder_tree_model_get_expanded (EMFolderTreeModel *model, const char *key)
void
em_folder_tree_model_set_expanded (EMFolderTreeModel *model, const char *key, gboolean expanded)
{
- gpointer okey, oval;
+ xmlNodePtr node, parent;
+ const char *name;
+ char *buf, *p;
- if (g_hash_table_lookup_extended (model->expanded, key, &okey, &oval)) {
- g_hash_table_remove (model->expanded, okey);
- g_free (okey);
+ if (model->expanded == NULL)
+ model->expanded = xmlNewDoc ("1.0");
+
+ if (!model->expanded->children) {
+ node = xmlNewDocNode (model->expanded, NULL, "tree-state", NULL);
+ xmlDocSetRootElement (model->expanded, node);
+ } else {
+ node = model->expanded->children;
}
- if (expanded)
- g_hash_table_insert (model->expanded, g_strdup (key), GINT_TO_POINTER (TRUE));
-}
-
-
-static void
-expanded_save (gpointer key, gpointer value, FILE *fp)
-{
- /* FIXME: don't save stale entries */
- if (!GPOINTER_TO_INT (value))
- return;
+ name = buf = g_alloca (strlen (key) + 1);
+ p = g_stpcpy (buf, key);
+ if (p[-1] == '/')
+ p[-1] = '\0';
+ p = NULL;
- camel_file_util_encode_string (fp, key);
+ do {
+ parent = node;
+ if ((p = strchr (name, '/')))
+ *p = '\0';
+
+ if (!(node = find_xml_node (node, name))) {
+ if (expanded) {
+ /* node (or parent node) doesn't exist, need to add it */
+ node = xmlNewChild (parent, NULL, "node", NULL);
+ xmlSetProp (node, "name", name);
+ xmlSetProp (node, "expand", "true");
+ } else {
+ /* node doesn't exist, so we don't need to set expanded to FALSE */
+ return;
+ }
+ } else if (p == NULL && !expanded) {
+ /* found the node we were looking for */
+ xmlSetProp (node, "expand", "false");
+ return;
+ }
+
+ name = p ? p + 1 : NULL;
+ } while (name);
}
void
em_folder_tree_model_save_expanded (EMFolderTreeModel *model)
{
- char *dirname, *tmpname;
- FILE *fp;
- int fd;
+ char *dirname;
+
+ if (model->expanded == NULL)
+ return;
dirname = g_path_get_dirname (model->filename);
if (camel_mkdir (dirname, 0777) == -1 && errno != EEXIST) {
@@ -919,44 +1032,54 @@ em_folder_tree_model_save_expanded (EMFolderTreeModel *model)
}
g_free (dirname);
- tmpname = g_strdup_printf ("%s~", model->filename);
-
- if (!(fp = fopen (tmpname, "w+"))) {
- g_free (tmpname);
- return;
- }
-
- g_hash_table_foreach (model->expanded, (GHFunc) expanded_save, fp);
-
- if (fflush (fp) != 0)
- goto exception;
-
- if ((fd = fileno (fp)) == -1)
- goto exception;
- if (fsync (fd) == -1)
- goto exception;
-
- fclose (fp);
- fp = NULL;
-
- if (rename (tmpname, model->filename) == -1)
- goto exception;
-
- g_free (tmpname);
-
- return;
+ e_xml_save_file (model->filename, model->expanded);
+}
+
+
+static void
+expand_foreach_r (EMFolderTreeModel *model, xmlNodePtr parent, const char *dirname, EMFTModelExpandFunc func, void *user_data)
+{
+ xmlNodePtr node = parent->children;
+ char *path, *name, *expand;
- exception:
+ while (node != NULL) {
+ if (!strcmp (node->name, "node")) {
+ name = xmlGetProp (node, "name");
+ expand = xmlGetProp (node, "expand");
+
+ if (expand && name && !strcmp (expand, "true")) {
+ if (dirname)
+ path = g_strdup_printf ("%s/%s", dirname, name);
+ else
+ path = g_strdup (name);
+
+ func (model, path, user_data);
+ if (node->children)
+ expand_foreach_r (model, node, path, func, user_data);
+ g_free (path);
+ }
+
+ xmlFree (expand);
+ xmlFree (name);
+ }
+
+ node = node->next;
+ }
+}
+
+void
+em_folder_tree_model_expand_foreach (EMFolderTreeModel *model, EMFTModelExpandFunc func, void *user_data)
+{
+ xmlNodePtr root;
- if (fp != NULL)
- fclose (fp);
+ root = model->expanded ? model->expanded->children : NULL;
+ if (!root || !root->children || strcmp (root->name, "tree-state") != 0)
+ return;
- unlink (tmpname);
- g_free (tmpname);
+ expand_foreach_r (model, root, NULL, func, user_data);
}
-
void
em_folder_tree_model_set_unread_count (EMFolderTreeModel *model, CamelStore *store, const char *path, int unread)
{
diff --git a/mail/em-folder-tree-model.h b/mail/em-folder-tree-model.h
index 103dc57052..7685399197 100644
--- a/mail/em-folder-tree-model.h
+++ b/mail/em-folder-tree-model.h
@@ -27,6 +27,8 @@
#include <gtk/gtktreednd.h>
#include <gtk/gtktreestore.h>
+#include <libxml/tree.h>
+
#include <camel/camel-store.h>
#include <e-util/e-account-list.h>
@@ -81,11 +83,11 @@ struct _EMFolderTreeModelStoreInfo {
struct _EMFolderTreeModel {
GtkTreeStore parent_object;
- char *filename; /* state filename */
+ char *filename; /* state filename */
+ xmlDocPtr expanded; /* saved expanded state from previous session */
GHashTable *store_hash; /* maps CamelStore's to store-info's */
GHashTable *uri_hash; /* maps URI's to GtkTreeRowReferences */
- GHashTable *expanded; /* saved expanded state from previous session */
EAccountList *accounts;
GHashTable *account_hash; /* maps accounts to store-info's */
@@ -101,6 +103,10 @@ struct _EMFolderTreeModelClass {
GtkTreePath *path,
GtkTreeIter *iter);
+ void (* loaded_row) (EMFolderTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter);
+
void (* folder_added) (EMFolderTreeModel *model,
const char *path,
const char *uri);
@@ -126,6 +132,9 @@ gboolean em_folder_tree_model_get_expanded (EMFolderTreeModel *model, const char
void em_folder_tree_model_set_expanded (EMFolderTreeModel *model, const char *key, gboolean expanded);
void em_folder_tree_model_save_expanded (EMFolderTreeModel *model);
+typedef void (* EMFTModelExpandFunc) (EMFolderTreeModel *model, const char *path, void *user_data);
+void em_folder_tree_model_expand_foreach (EMFolderTreeModel *model, EMFTModelExpandFunc func, void *user_data);
+
void em_folder_tree_model_set_unread_count (EMFolderTreeModel *model, CamelStore *store, const char *path, int unread);
#ifdef __cplusplus
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);
diff --git a/mail/mail-component.c b/mail/mail-component.c
index 7499420131..c519e108dd 100644
--- a/mail/mail-component.c
+++ b/mail/mail-component.c
@@ -632,7 +632,6 @@ impl_requestCreateItem (PortableServer_Servant servant,
g_signal_connect (dialog, "response", G_CALLBACK(emc_new_folder_response), mc);
gtk_widget_show(dialog);
} else {
-
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_GNOME_Evolution_Component_UnknownType, NULL);
return;