aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog38
-rw-r--r--mail/em-folder-tree-model.c412
-rw-r--r--mail/em-folder-tree-model.h28
-rw-r--r--mail/em-folder-tree.c449
-rw-r--r--mail/em-folder-tree.h3
-rw-r--r--mail/mail-component.c18
6 files changed, 482 insertions, 466 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 8d1e933446..be75dee5d6 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -16,6 +16,44 @@
2003-12-01 Jeffrey Stedfast <fejj@ximian.com>
+ * em-folder-tree.c (em_folder_tree_get_folder_info__got): Updated
+ to call em_folder_tree_model_set_folder_info().
+ (folder_subscribed_cb): Removed.
+ (folder_unsubscribed_cb): Removed.
+ (folder_created_cb): Removed.
+ (folder_deleted_cb): Removed.
+ (folder_renamed_cb): Removed.
+
+ * em-folder-tree-model.c (em_folder_tree_store_set_folder_info):
+ New function to replace tree_store_set_folder_info() which had
+ been in em-folder-tree.c
+ (em_folder_tree_model_remove_uri): Made private.
+ (em_folder_tree_model_remove_store_info): Made private.
+ (em_folder_tree_model_remove_folders): New function to replace
+ remove_folders() from em-folder-tree.c
+ (em_folder_tree_model_new): No longer takes any args.
+
+ * em-folder-tree.c (em_folder_tree_new): Updated.
+
+ * mail-component.c (add_store): Add the store to the model rather
+ than the treeview.
+ (impl_createControls): create a new treeview based on the
+ already-instantiated model.
+ (mail_component_init): Create a new tree model.
+ (mail_component_remove_store): Remove the store from the model
+ directly.
+ (mail_component_get_tree_model): Updated.
+
+ * em-folder-tree.c (folder_unsubscribed_cb): Call
+ em_folder_tree_model_remove_folders() rather than the deprecated
+ internal remove_folders() function.
+ (folder_renamed_cb): Same.
+ (em_folder_tree_remove_store): Removed.
+ (em_folder_tree_add_store): Removed.
+ (remove_folders): Removed.
+
+2003-12-01 Jeffrey Stedfast <fejj@ximian.com>
+
* em-composer-utils.c (composer_get_message): rfc2047 encode the
Organization header value.
diff --git a/mail/em-folder-tree-model.c b/mail/em-folder-tree-model.c
index f6f7d6cc27..677ab8d0fe 100644
--- a/mail/em-folder-tree-model.c
+++ b/mail/em-folder-tree-model.c
@@ -25,10 +25,25 @@
#include <config.h>
#endif
+#include <string.h>
+
+#include "mail-config.h"
+
#include "em-marshal.h"
#include "em-folder-tree-model.h"
+static GType col_types[] = {
+ G_TYPE_STRING, /* display name */
+ G_TYPE_POINTER, /* store object */
+ G_TYPE_STRING, /* path */
+ G_TYPE_STRING, /* uri */
+ G_TYPE_UINT, /* unread count */
+ G_TYPE_BOOLEAN, /* is a store node */
+ G_TYPE_BOOLEAN, /* has not-yet-loaded subfolders */
+};
+
+
/* GObject virtual method overrides */
static void em_folder_tree_model_class_init (EMFolderTreeModelClass *klass);
static void em_folder_tree_model_init (EMFolderTreeModel *model);
@@ -321,18 +336,348 @@ model_drag_data_delete (GtkTreeDragSource *drag_source, GtkTreePath *src_path)
EMFolderTreeModel *
-em_folder_tree_model_new (int n_columns, GType *types)
+em_folder_tree_model_new (void)
{
EMFolderTreeModel *model;
model = g_object_new (EM_TYPE_FOLDER_TREE_MODEL, NULL);
- gtk_tree_store_set_column_types ((GtkTreeStore *) model, n_columns, types);
+ gtk_tree_store_set_column_types ((GtkTreeStore *) model, NUM_COLUMNS, col_types);
return model;
}
void
+em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *iter,
+ struct _EMFolderTreeModelStoreInfo *si,
+ CamelFolderInfo *fi)
+{
+ GtkTreeRowReference *uri_row, *path_row;
+ unsigned int unread;
+ EAccount *account;
+ GtkTreePath *path;
+ GtkTreeIter sub;
+ gboolean load;
+ char *node;
+
+ load = !fi->child && (fi->flags & CAMEL_FOLDER_CHILDREN) && !(fi->flags & 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->url), uri_row);
+ g_hash_table_insert (si->path_hash, g_strdup (fi->path), path_row);
+
+ unread = fi->unread_message_count == -1 ? 0 : fi->unread_message_count;
+
+ gtk_tree_store_set ((GtkTreeStore *) model, iter,
+ COL_STRING_DISPLAY_NAME, fi->name,
+ COL_POINTER_CAMEL_STORE, si->store,
+ COL_STRING_FOLDER_PATH, fi->path,
+ COL_STRING_URI, fi->url,
+ COL_UINT_UNREAD, unread,
+ COL_BOOL_IS_STORE, FALSE,
+ COL_BOOL_LOAD_SUBDIRS, load,
+ -1);
+
+ node = fi->path;
+
+ 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->sibling;
+ } while (fi);
+ } else if (load) {
+ /* create a placeholder node for our subfolders... */
+ gtk_tree_store_append ((GtkTreeStore *) model, &sub, iter);
+ gtk_tree_store_set ((GtkTreeStore *) model, &sub,
+ COL_STRING_DISPLAY_NAME, _("Loading..."),
+ COL_POINTER_CAMEL_STORE, si->store,
+ COL_STRING_FOLDER_PATH, fi->path,
+ COL_BOOL_LOAD_SUBDIRS, TRUE,
+ COL_BOOL_IS_STORE, FALSE,
+ COL_STRING_URI, fi->url,
+ COL_UINT_UNREAD, 0,
+ -1);
+ }
+#if 0
+ /* FIXME: need to somehow get access to the appropriate treeview widget... */
+ if ((account = mail_config_get_account_by_name (si->display_name)))
+ node = g_strdup_printf ("%s:%s", account->uid, node);
+ else
+ node = g_strdup_printf ("%s:%s", si->display_name, node);
+
+ if (g_hash_table_lookup (priv->expanded, node)) {
+ printf ("expanding node '%s'\n", node);
+ gtk_tree_view_expand_to_path (priv->treeview, path);
+ }
+
+ gtk_tree_path_free (path);
+ g_free (node);
+#endif
+}
+
+
+static void
+folder_subscribed_cb (CamelStore *store, void *event_data, EMFolderTreeModel *model)
+{
+ struct _EMFolderTreeModelStoreInfo *si;
+ CamelFolderInfo *fi = event_data;
+ GtkTreeRowReference *row;
+ GtkTreeIter parent, iter;
+ GtkTreePath *path;
+ gboolean load;
+ char *dirname;
+
+ if (!(si = g_hash_table_lookup (model->store_hash, store)))
+ return;
+
+ /* make sure we don't already know about it? */
+ if (g_hash_table_lookup (si->path_hash, fi->path))
+ return;
+
+ /* get our parent folder's path */
+ if (!(dirname = g_path_get_dirname (fi->path)))
+ return;
+
+ if (!strcmp (dirname, "/")) {
+ /* user subscribed to a toplevel folder */
+ row = si->row;
+ g_free (dirname);
+ } else {
+ row = g_hash_table_lookup (si->path_hash, dirname);
+ g_free (dirname);
+
+ /* if row is NULL, don't bother adding to the tree,
+ * when the user expands enough nodes - it will be
+ * added auto-magically */
+ if (row == NULL)
+ return;
+ }
+
+ path = gtk_tree_row_reference_get_path (row);
+ if (!(gtk_tree_model_get_iter ((GtkTreeModel *) model, &parent, path))) {
+ gtk_tree_path_free (path);
+ return;
+ }
+
+ gtk_tree_path_free (path);
+
+ /* make sure parent's subfolders have already been loaded */
+ gtk_tree_model_get ((GtkTreeModel *) model, &parent, COL_BOOL_LOAD_SUBDIRS, &load, -1);
+ if (load)
+ return;
+
+ /* append a new node */
+ gtk_tree_store_append ((GtkTreeStore *) model, &iter, &parent);
+
+ em_folder_tree_model_set_folder_info (model, &iter, si, fi);
+}
+
+static void
+folder_unsubscribed_cb (CamelStore *store, void *event_data, EMFolderTreeModel *model)
+{
+ struct _EMFolderTreeModelStoreInfo *si;
+ CamelFolderInfo *fi = event_data;
+ GtkTreeRowReference *row;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+
+ if (!(si = g_hash_table_lookup (model->store_hash, store)))
+ return;
+
+ if (!(row = g_hash_table_lookup (si->path_hash, fi->path)))
+ return;
+
+ path = gtk_tree_row_reference_get_path (row);
+ if (!(gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, path))) {
+ gtk_tree_path_free (path);
+ return;
+ }
+
+ em_folder_tree_model_remove_folders (model, si, &iter);
+}
+
+static void
+folder_created_cb (CamelStore *store, void *event_data, EMFolderTreeModel *model)
+{
+ /* we only want created events to do more work if we don't support subscriptions */
+ if (!camel_store_supports_subscriptions (store))
+ folder_subscribed_cb (store, event_data, model);
+}
+
+static void
+folder_deleted_cb (CamelStore *store, void *event_data, EMFolderTreeModel *model)
+{
+ /* we only want deleted events to do more work if we don't support subscriptions */
+ if (!camel_store_supports_subscriptions (store))
+ folder_unsubscribed_cb (store, event_data, model);
+}
+
+static void
+folder_renamed_cb (CamelStore *store, void *event_data, EMFolderTreeModel *model)
+{
+ struct _EMFolderTreeModelStoreInfo *si;
+ CamelRenameInfo *info = event_data;
+ GtkTreeRowReference *row;
+ GtkTreeIter root, iter;
+ GtkTreePath *path;
+ char *parent, *p;
+
+ if (!(si = g_hash_table_lookup (model->store_hash, store)))
+ return;
+
+ parent = g_strdup_printf ("/%s", info->old_base);
+ if (!(row = g_hash_table_lookup (si->path_hash, parent))) {
+ g_free (parent);
+ return;
+ }
+ g_free (parent);
+
+ path = gtk_tree_row_reference_get_path (row);
+ if (!(gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, path))) {
+ gtk_tree_path_free (path);
+ return;
+ }
+
+ em_folder_tree_model_remove_folders (model, si, &iter);
+
+ parent = g_strdup (info->new->path);
+ if ((p = strrchr (parent + 1, '/')))
+ *p = '\0';
+
+ if (!strcmp (parent, "/")) {
+ /* renamed to a toplevel folder on the store */
+ path = gtk_tree_row_reference_get_path (si->row);
+ } else {
+ if (!(row = g_hash_table_lookup (si->path_hash, parent))) {
+ /* NOTE: this should never happen, but I
+ * suppose if it does in reality, we can add
+ * code here to add the missing nodes to the
+ * tree */
+ g_assert_not_reached ();
+ g_free (parent);
+ return;
+ }
+
+ path = gtk_tree_row_reference_get_path (row);
+ }
+
+ g_free (parent);
+
+ if (!gtk_tree_model_get_iter ((GtkTreeModel *) model, &root, path)) {
+ gtk_tree_path_free (path);
+ g_assert_not_reached ();
+ return;
+ }
+
+ gtk_tree_store_append ((GtkTreeStore *) model, &iter, &root);
+ em_folder_tree_model_set_folder_info (model, &iter, si, info->new);
+}
+
+
+void
+em_folder_tree_model_add_store (EMFolderTreeModel *model, CamelStore *store, const char *display_name)
+{
+ struct _EMFolderTreeModelStoreInfo *si;
+ GtkTreeRowReference *row;
+ GtkTreeIter root, iter;
+ GtkTreePath *path;
+ EAccount *account;
+ char *node, *uri;
+
+ g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
+ g_return_if_fail (CAMEL_IS_STORE (store));
+ g_return_if_fail (display_name != NULL);
+
+ if ((si = g_hash_table_lookup (model->store_hash, store))) {
+ const char *name;
+
+ path = gtk_tree_row_reference_get_path (si->row);
+ gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, path);
+ gtk_tree_path_free (path);
+
+ gtk_tree_model_get ((GtkTreeModel *) model, &iter, COL_STRING_DISPLAY_NAME, (char **) &name, -1);
+
+ g_warning ("the store `%s' is already in the folder tree as `%s'",
+ display_name, name);
+
+ return;
+ }
+
+ uri = camel_url_to_string (((CamelService *) store)->url, CAMEL_URL_HIDE_ALL);
+
+ /* add the store to the tree */
+ gtk_tree_store_append ((GtkTreeStore *) model, &iter, NULL);
+ gtk_tree_store_set ((GtkTreeStore *) model, &iter,
+ COL_STRING_DISPLAY_NAME, display_name,
+ COL_POINTER_CAMEL_STORE, store,
+ COL_STRING_FOLDER_PATH, "/",
+ COL_BOOL_LOAD_SUBDIRS, TRUE,
+ COL_BOOL_IS_STORE, TRUE,
+ COL_STRING_URI, uri, -1);
+
+ 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);
+ camel_object_ref (store);
+ si->store = store;
+ si->row = row;
+ si->path_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (model->store_hash, store, si);
+
+ /* each store has folders... but we don't load them until the user demands them */
+ root = iter;
+ gtk_tree_store_append ((GtkTreeStore *) model, &iter, &root);
+ gtk_tree_store_set ((GtkTreeStore *) model, &iter,
+ COL_STRING_DISPLAY_NAME, _("Loading..."),
+ COL_POINTER_CAMEL_STORE, store,
+ COL_STRING_FOLDER_PATH, "/",
+ COL_BOOL_LOAD_SUBDIRS, TRUE,
+ COL_BOOL_IS_STORE, FALSE,
+ COL_STRING_URI, uri,
+ COL_UINT_UNREAD, 0,
+ -1);
+
+ g_free (uri);
+
+#if 0
+ /* FIXME: how to do this now that it is being done in the
+ * model instead of the tree widget code??? need to somehow
+ * get access to the appropriate treeview widget... */
+ if ((account = mail_config_get_account_by_name (display_name)))
+ node = g_strdup_printf ("%s:/", account->uid);
+ else
+ node = g_strdup_printf ("%s:/", display_name);
+
+ if (g_hash_table_lookup (priv->expanded, node)) {
+ path = gtk_tree_model_get_path ((GtkTreeModel *) model, &iter);
+ gtk_tree_view_expand_to_path (priv->treeview, path);
+ gtk_tree_path_free (path);
+ }
+
+ g_free (node);
+#endif
+
+ /* listen to store events */
+#define CAMEL_CALLBACK(func) ((CamelObjectEventHookFunc) func)
+ si->created_id = camel_object_hook_event (store, "folder_created", CAMEL_CALLBACK (folder_created_cb), model);
+ si->deleted_id = camel_object_hook_event (store, "folder_deleted", CAMEL_CALLBACK (folder_deleted_cb), model);
+ 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);
+}
+
+
+static void
em_folder_tree_model_remove_uri (EMFolderTreeModel *model, const char *uri)
{
GtkTreeRowReference *row;
@@ -347,7 +692,7 @@ em_folder_tree_model_remove_uri (EMFolderTreeModel *model, const char *uri)
}
-void
+static void
em_folder_tree_model_remove_store_info (EMFolderTreeModel *model, CamelStore *store)
{
struct _EMFolderTreeModelStoreInfo *si;
@@ -361,3 +706,64 @@ em_folder_tree_model_remove_store_info (EMFolderTreeModel *model, CamelStore *st
g_hash_table_remove (model->store_hash, si->store);
store_info_free (si);
}
+
+
+void
+em_folder_tree_model_remove_folders (EMFolderTreeModel *model, struct _EMFolderTreeModelStoreInfo *si, GtkTreeIter *toplevel)
+{
+ GtkTreeRowReference *row;
+ char *uri, *folder_path;
+ gboolean is_store, go;
+ GtkTreeIter iter;
+
+ if (gtk_tree_model_iter_children ((GtkTreeModel *) model, &iter, toplevel)) {
+ do {
+ GtkTreeIter next = iter;
+
+ go = gtk_tree_model_iter_next ((GtkTreeModel *) model, &next);
+ em_folder_tree_model_remove_folders (model, si, &iter);
+ iter = next;
+ } while (go);
+ }
+
+ gtk_tree_model_get ((GtkTreeModel *) model, toplevel, COL_STRING_URI, &uri,
+ COL_STRING_FOLDER_PATH, &folder_path,
+ COL_BOOL_IS_STORE, &is_store, -1);
+
+ if ((row = g_hash_table_lookup (si->path_hash, folder_path))) {
+ g_hash_table_remove (si->path_hash, folder_path);
+ gtk_tree_row_reference_free (row);
+ }
+
+ em_folder_tree_model_remove_uri (model, uri);
+
+ gtk_tree_store_remove ((GtkTreeStore *) model, toplevel);
+
+ if (is_store)
+ em_folder_tree_model_remove_store_info (model, si->store);
+}
+
+
+void
+em_folder_tree_model_remove_store (EMFolderTreeModel *model, CamelStore *store)
+{
+ struct _EMFolderTreeModelStoreInfo *si;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+
+ g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
+ g_return_if_fail (CAMEL_IS_STORE (store));
+
+ if (!(si = g_hash_table_lookup (model->store_hash, store))) {
+ g_warning ("the store `%s' is not in the folder tree", si->display_name);
+
+ return;
+ }
+
+ path = gtk_tree_row_reference_get_path (si->row);
+ gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, path);
+ gtk_tree_path_free (path);
+
+ /* recursively remove subfolders and finally the toplevel store */
+ em_folder_tree_model_remove_folders (model, si, &iter);
+}
diff --git a/mail/em-folder-tree-model.h b/mail/em-folder-tree-model.h
index f120c0dc62..e8755f0578 100644
--- a/mail/em-folder-tree-model.h
+++ b/mail/em-folder-tree-model.h
@@ -45,6 +45,22 @@ typedef struct _EMFolderTreeModel EMFolderTreeModel;
typedef struct _EMFolderTreeModelClass EMFolderTreeModelClass;
typedef struct _EMFolderTreeModelStoreInfo EMFolderTreeModelStoreInfo;
+enum {
+ COL_STRING_DISPLAY_NAME, /* string that appears in the tree */
+ COL_POINTER_CAMEL_STORE, /* CamelStore object */
+ COL_STRING_FOLDER_PATH, /* if node is a folder, the full path of the folder */
+ COL_STRING_URI, /* the uri to get the store or
+ * folder object */
+ COL_UINT_UNREAD, /* unread count */
+
+ COL_BOOL_IS_STORE, /* toplevel store node? */
+ COL_BOOL_LOAD_SUBDIRS, /* %TRUE only if the store/folder
+ * has subfolders which have not yet
+ * been added to the tree */
+ NUM_COLUMNS
+};
+
+
struct _EMFolderTreeModelStoreInfo {
CamelStore *store;
GtkTreeRowReference *row;
@@ -91,11 +107,17 @@ struct _EMFolderTreeModelClass {
GType em_folder_tree_model_get_type (void);
-EMFolderTreeModel *em_folder_tree_model_new (int n_columns, GType *types);
+EMFolderTreeModel *em_folder_tree_model_new (void);
+
+void em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *iter,
+ struct _EMFolderTreeModelStoreInfo *si,
+ CamelFolderInfo *fi);
-void em_folder_tree_model_remove_uri (EMFolderTreeModel *model, const char *uri);
-void em_folder_tree_model_remove_store_info (EMFolderTreeModel *model, CamelStore *store);
+void em_folder_tree_model_add_store (EMFolderTreeModel *model, CamelStore *store, const char *display_name);
+void em_folder_tree_model_remove_store (EMFolderTreeModel *model, CamelStore *store);
+void em_folder_tree_model_remove_folders (EMFolderTreeModel *model, struct _EMFolderTreeModelStoreInfo *si,
+ GtkTreeIter *toplevel);
#ifdef __cplusplus
}
diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c
index 48c71f164d..7aad5a8260 100644
--- a/mail/em-folder-tree.c
+++ b/mail/em-folder-tree.c
@@ -64,30 +64,6 @@
#define d(x) x
-enum {
- COL_STRING_DISPLAY_NAME, /* string that appears in the tree */
- COL_POINTER_CAMEL_STORE, /* CamelStore object */
- COL_STRING_FOLDER_PATH, /* if node is a folder, the full path of the folder */
- COL_STRING_URI, /* the uri to get the store or
- * folder object */
- COL_UINT_UNREAD, /* unread count */
-
- COL_BOOL_IS_STORE, /* toplevel store node? */
- COL_BOOL_LOAD_SUBDIRS, /* %TRUE only if the store/folder
- * has subfolders which have not yet
- * been added to the tree */
- NUM_COLUMNS
-};
-
-static GType col_types[] = {
- G_TYPE_STRING, /* display name */
- G_TYPE_POINTER, /* store object */
- G_TYPE_STRING, /* path */
- G_TYPE_STRING, /* uri */
- G_TYPE_UINT, /* unread count */
- G_TYPE_BOOLEAN, /* is a store node */
- G_TYPE_BOOLEAN, /* has not-yet-loaded subfolders */
-};
struct _EMFolderTreePrivate {
GtkTreeView *treeview;
@@ -884,7 +860,7 @@ em_folder_tree_new (void)
EMFolderTreeModel *model;
EMFolderTree *emft;
- model = em_folder_tree_model_new (NUM_COLUMNS, col_types);
+ model = em_folder_tree_model_new ();
emft = (EMFolderTree *) em_folder_tree_new_with_model (model);
priv = emft->priv;
@@ -984,96 +960,6 @@ em_folder_tree_new_with_model (EMFolderTreeModel *model)
}
-static void
-tree_store_set_folder_info (GtkTreeStore *model, GtkTreeIter *iter,
- struct _EMFolderTreePrivate *priv,
- struct _EMFolderTreeModelStoreInfo *si,
- CamelFolderInfo *fi)
-{
- GtkTreeRowReference *uri_row, *path_row;
- unsigned int unread;
- EAccount *account;
- GtkTreePath *path;
- GtkTreeIter sub;
- gboolean load;
- char *node;
-
- load = !fi->child && (fi->flags & CAMEL_FOLDER_CHILDREN) && !(fi->flags & 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 (priv->model->uri_hash, g_strdup (fi->url), uri_row);
- g_hash_table_insert (si->path_hash, g_strdup (fi->path), path_row);
-
- unread = fi->unread_message_count == -1 ? 0 : fi->unread_message_count;
-
- gtk_tree_store_set (model, iter,
- COL_STRING_DISPLAY_NAME, fi->name,
- COL_POINTER_CAMEL_STORE, si->store,
- COL_STRING_FOLDER_PATH, fi->path,
- COL_STRING_URI, fi->url,
- COL_UINT_UNREAD, unread,
- COL_BOOL_IS_STORE, FALSE,
- COL_BOOL_LOAD_SUBDIRS, load,
- -1);
-
- node = fi->path;
-
- if (fi->child) {
- fi = fi->child;
-
- do {
- gtk_tree_store_append (model, &sub, iter);
- tree_store_set_folder_info ((GtkTreeStore *) model, &sub, priv, si, fi);
- fi = fi->sibling;
- } while (fi);
- } else if (load) {
- /* create a placeholder node for our subfolders... */
- gtk_tree_store_append (model, &sub, iter);
- gtk_tree_store_set (model, &sub,
- COL_STRING_DISPLAY_NAME, _("Loading..."),
- COL_POINTER_CAMEL_STORE, si->store,
- COL_STRING_FOLDER_PATH, fi->path,
- COL_BOOL_LOAD_SUBDIRS, TRUE,
- COL_BOOL_IS_STORE, FALSE,
- COL_STRING_URI, fi->url,
- COL_UINT_UNREAD, 0,
- -1);
-#if 0
- if ((account = mail_config_get_account_by_name (si->display_name)))
- node = g_strdup_printf ("%s:%s", account->uid, fi->path);
- else
- node = g_strdup_printf ("%s:%s", si->display_name, fi->path);
-
- if (g_hash_table_lookup (priv->expanded, node)) {
- printf ("expanding node '%s'\n", node);
- path = gtk_tree_model_get_path ((GtkTreeModel *) model, &sub);
- gtk_tree_view_expand_to_path (priv->treeview, path);
- gtk_tree_path_free (path);
- }
-
- g_free (node);
-#endif
- }
-#if 1
- if ((account = mail_config_get_account_by_name (si->display_name)))
- node = g_strdup_printf ("%s:%s", account->uid, node);
- else
- node = g_strdup_printf ("%s:%s", si->display_name, node);
-
- if (g_hash_table_lookup (priv->expanded, node)) {
- printf ("expanding node '%s'\n", node);
- gtk_tree_view_expand_to_path (priv->treeview, path);
- }
-
- gtk_tree_path_free (path);
- g_free (node);
-#endif
-}
-
#if 0
static void
dump_fi (CamelFolderInfo *fi, int depth)
@@ -1140,7 +1026,7 @@ em_folder_tree_get_folder_info__got (struct _mail_msg *mm)
return;
/* check that our parent folder hasn't been deleted/unsubscribed */
- if (!gtk_tree_row_reference_is_valid (m->root))
+ if (!gtk_tree_row_reference_valid (m->root))
return;
if (!(si = g_hash_table_lookup (priv->model->store_hash, m->store))) {
@@ -1178,7 +1064,7 @@ em_folder_tree_get_folder_info__got (struct _mail_msg *mm)
gtk_tree_store_remove (model, &iter);
} else {
do {
- tree_store_set_folder_info (model, &iter, priv, si, fi);
+ em_folder_tree_model_set_folder_info (priv->model, &iter, si, fi);
if ((fi = fi->sibling) != NULL)
gtk_tree_store_append (model, &iter, &root);
@@ -2069,335 +1955,6 @@ tree_selection_changed (GtkTreeSelection *selection, EMFolderTree *emft)
}
-static void
-folder_subscribed_cb (CamelStore *store, void *event_data, EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
- struct _EMFolderTreeModelStoreInfo *si;
- CamelFolderInfo *fi = event_data;
- GtkTreeRowReference *row;
- GtkTreeIter parent, iter;
- GtkTreeModel *model;
- GtkTreePath *path;
- gboolean load;
- char *dirname;
-
- if (!(si = g_hash_table_lookup (priv->model->store_hash, store)))
- return;
-
- /* make sure we don't already know about it? */
- if (g_hash_table_lookup (si->path_hash, fi->path))
- return;
-
- /* get our parent folder's path */
- if (!(dirname = g_path_get_dirname (fi->path)))
- return;
-
- if (!strcmp (dirname, "/")) {
- /* user subscribed to a toplevel folder */
- row = si->row;
- g_free (dirname);
- } else {
- row = g_hash_table_lookup (si->path_hash, dirname);
- g_free (dirname);
-
- /* if row is NULL, don't bother adding to the tree,
- * when the user expands enough nodes - it will be
- * added auto-magically */
- if (row == NULL)
- return;
- }
-
- path = gtk_tree_row_reference_get_path (row);
- model = gtk_tree_view_get_model (priv->treeview);
- if (!(gtk_tree_model_get_iter (model, &parent, path))) {
- gtk_tree_path_free (path);
- return;
- }
-
- gtk_tree_path_free (path);
-
- /* make sure parent's subfolders have already been loaded */
- gtk_tree_model_get (model, &parent, COL_BOOL_LOAD_SUBDIRS, &load, -1);
- if (load)
- return;
-
- /* append a new node */
- gtk_tree_store_append ((GtkTreeStore *) model, &iter, &parent);
-
- tree_store_set_folder_info ((GtkTreeStore *) model, &iter, priv, si, fi);
-}
-
-static void
-remove_folders (EMFolderTree *emft, GtkTreeModel *model, struct _EMFolderTreeModelStoreInfo *si, GtkTreeIter *toplevel)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
- GtkTreeRowReference *row;
- char *uri, *folder_path;
- gboolean is_store, go;
- GtkTreeIter iter;
-
- if (gtk_tree_model_iter_children (model, &iter, toplevel)) {
- do {
- GtkTreeIter next = iter;
-
- go = gtk_tree_model_iter_next (model, &next);
- remove_folders (emft, model, si, &iter);
- iter = next;
- } while (go);
- }
-
- gtk_tree_model_get (model, toplevel, COL_STRING_URI, &uri,
- COL_STRING_FOLDER_PATH, &folder_path,
- COL_BOOL_IS_STORE, &is_store, -1);
-
- if ((row = g_hash_table_lookup (si->path_hash, folder_path))) {
- g_hash_table_remove (si->path_hash, folder_path);
- gtk_tree_row_reference_free (row);
- }
-
- em_folder_tree_model_remove_uri (priv->model, uri);
-
- gtk_tree_store_remove ((GtkTreeStore *) model, toplevel);
-
- if (is_store)
- em_folder_tree_model_remove_store_info (priv->model, si->store);
-}
-
-static void
-folder_unsubscribed_cb (CamelStore *store, void *event_data, EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
- struct _EMFolderTreeModelStoreInfo *si;
- CamelFolderInfo *fi = event_data;
- GtkTreeRowReference *row;
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
-
- if (!(si = g_hash_table_lookup (priv->model->store_hash, store)))
- return;
-
- if (!(row = g_hash_table_lookup (si->path_hash, fi->path)))
- return;
-
- path = gtk_tree_row_reference_get_path (row);
- model = gtk_tree_view_get_model (emft->priv->treeview);
- if (!(gtk_tree_model_get_iter (model, &iter, path))) {
- gtk_tree_path_free (path);
- return;
- }
-
- remove_folders (emft, model, si, &iter);
-}
-
-static void
-folder_created_cb (CamelStore *store, void *event_data, EMFolderTree *emft)
-{
- /* we only want created events to do more work if we don't support subscriptions */
- if (!camel_store_supports_subscriptions (store))
- folder_subscribed_cb (store, event_data, emft);
-}
-
-static void
-folder_deleted_cb (CamelStore *store, void *event_data, EMFolderTree *emft)
-{
- /* we only want deleted events to do more work if we don't support subscriptions */
- if (!camel_store_supports_subscriptions (store))
- folder_unsubscribed_cb (store, event_data, emft);
-}
-
-static void
-folder_renamed_cb (CamelStore *store, void *event_data, EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
- struct _EMFolderTreeModelStoreInfo *si;
- CamelRenameInfo *info = event_data;
- GtkTreeRowReference *row;
- GtkTreeIter root, iter;
- GtkTreeModel *model;
- GtkTreePath *path;
- char *parent, *p;
-
- if (!(si = g_hash_table_lookup (priv->model->store_hash, store)))
- return;
-
- parent = g_strdup_printf ("/%s", info->old_base);
- if (!(row = g_hash_table_lookup (si->path_hash, parent))) {
- g_free (parent);
- return;
- }
- g_free (parent);
-
- path = gtk_tree_row_reference_get_path (row);
- model = gtk_tree_view_get_model (emft->priv->treeview);
- if (!(gtk_tree_model_get_iter (model, &iter, path))) {
- gtk_tree_path_free (path);
- return;
- }
-
- remove_folders (emft, model, si, &iter);
-
- parent = g_strdup (info->new->path);
- if ((p = strrchr (parent + 1, '/')))
- *p = '\0';
-
- if (!strcmp (parent, "/")) {
- /* renamed to a toplevel folder on the store */
- path = gtk_tree_row_reference_get_path (si->row);
- } else {
- if (!(row = g_hash_table_lookup (si->path_hash, parent))) {
- /* NOTE: this should never happen, but I
- * suppose if it does in reality, we can add
- * code here to add the missing nodes to the
- * tree */
- g_assert_not_reached ();
- g_free (parent);
- return;
- }
-
- path = gtk_tree_row_reference_get_path (row);
- }
-
- g_free (parent);
-
- if (!gtk_tree_model_get_iter (model, &root, path)) {
- gtk_tree_path_free (path);
- g_assert_not_reached ();
- return;
- }
-
- gtk_tree_store_append ((GtkTreeStore *) model, &iter, &root);
- tree_store_set_folder_info ((GtkTreeStore *) model, &iter, priv, si, info->new);
-}
-
-
-void
-em_folder_tree_add_store (EMFolderTree *emft, CamelStore *store, const char *display_name)
-{
- struct _EMFolderTreeModelStoreInfo *si;
- struct _EMFolderTreePrivate *priv;
- GtkTreeRowReference *row;
- GtkTreeIter root, iter;
- GtkTreeStore *model;
- GtkTreePath *path;
- EAccount *account;
- char *node, *uri;
-
- g_return_if_fail (EM_IS_FOLDER_TREE (emft));
- g_return_if_fail (CAMEL_IS_STORE (store));
- g_return_if_fail (display_name != NULL);
-
- priv = emft->priv;
- model = (GtkTreeStore *) gtk_tree_view_get_model (priv->treeview);
-
- if ((si = g_hash_table_lookup (priv->model->store_hash, store))) {
- const char *name;
-
- path = gtk_tree_row_reference_get_path (si->row);
- gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, path);
- gtk_tree_path_free (path);
-
- gtk_tree_model_get ((GtkTreeModel *) model, &iter, COL_STRING_DISPLAY_NAME, (char **) &name, -1);
-
- g_warning ("the store `%s' is already in the folder tree as `%s'",
- display_name, name);
-
- return;
- }
-
- uri = camel_url_to_string (((CamelService *) store)->url, CAMEL_URL_HIDE_ALL);
-
- /* add the store to the tree */
- gtk_tree_store_append (model, &iter, NULL);
- gtk_tree_store_set (model, &iter,
- COL_STRING_DISPLAY_NAME, display_name,
- COL_POINTER_CAMEL_STORE, store,
- COL_STRING_FOLDER_PATH, "/",
- COL_BOOL_LOAD_SUBDIRS, TRUE,
- COL_BOOL_IS_STORE, TRUE,
- COL_STRING_URI, uri, -1);
-
- 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);
- camel_object_ref (store);
- si->store = store;
- si->row = row;
- si->path_hash = g_hash_table_new (g_str_hash, g_str_equal);
- g_hash_table_insert (priv->model->store_hash, store, si);
-
- /* each store has folders... but we don't load them until the user demands them */
- root = iter;
- gtk_tree_store_append (model, &iter, &root);
- gtk_tree_store_set (model, &iter,
- COL_STRING_DISPLAY_NAME, _("Loading..."),
- COL_POINTER_CAMEL_STORE, store,
- COL_STRING_FOLDER_PATH, "/",
- COL_BOOL_LOAD_SUBDIRS, TRUE,
- COL_BOOL_IS_STORE, FALSE,
- COL_STRING_URI, uri,
- COL_UINT_UNREAD, 0,
- -1);
-
- g_free (uri);
-
- if ((account = mail_config_get_account_by_name (display_name)))
- node = g_strdup_printf ("%s:/", account->uid);
- else
- node = g_strdup_printf ("%s:/", display_name);
-
- if (g_hash_table_lookup (priv->expanded, node)) {
- path = gtk_tree_model_get_path ((GtkTreeModel *) model, &iter);
- gtk_tree_view_expand_to_path (priv->treeview, path);
- gtk_tree_path_free (path);
- }
-
- g_free (node);
-
- /* listen to store events */
-#define CAMEL_CALLBACK(func) ((CamelObjectEventHookFunc) func)
- si->created_id = camel_object_hook_event (store, "folder_created", CAMEL_CALLBACK (folder_created_cb), emft);
- si->deleted_id = camel_object_hook_event (store, "folder_deleted", CAMEL_CALLBACK (folder_deleted_cb), emft);
- si->renamed_id = camel_object_hook_event (store, "folder_renamed", CAMEL_CALLBACK (folder_renamed_cb), emft);
- si->subscribed_id = camel_object_hook_event (store, "folder_subscribed", CAMEL_CALLBACK (folder_subscribed_cb), emft);
- si->unsubscribed_id = camel_object_hook_event (store, "folder_unsubscribed", CAMEL_CALLBACK (folder_unsubscribed_cb), emft);
-}
-
-
-void
-em_folder_tree_remove_store (EMFolderTree *emft, CamelStore *store)
-{
- struct _EMFolderTreeModelStoreInfo *si;
- struct _EMFolderTreePrivate *priv;
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
-
- g_return_if_fail (EM_IS_FOLDER_TREE (emft));
- g_return_if_fail (CAMEL_IS_STORE (store));
-
- priv = emft->priv;
- model = gtk_tree_view_get_model (priv->treeview);
-
- if (!(si = g_hash_table_lookup (priv->model->store_hash, store))) {
- g_warning ("the store `%s' is not in the folder tree", si->display_name);
-
- return;
- }
-
- path = gtk_tree_row_reference_get_path (si->row);
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_path_free (path);
-
- /* recursively remove subfolders and finally the toplevel store */
- remove_folders (emft, model, si, &iter);
-}
-
-
void
em_folder_tree_set_selected (EMFolderTree *emft, const char *uri)
{
diff --git a/mail/em-folder-tree.h b/mail/em-folder-tree.h
index b4b845afac..71971b6585 100644
--- a/mail/em-folder-tree.h
+++ b/mail/em-folder-tree.h
@@ -63,9 +63,6 @@ GType em_folder_tree_get_type (void);
GtkWidget *em_folder_tree_new (void);
GtkWidget *em_folder_tree_new_with_model (EMFolderTreeModel *model);
-void em_folder_tree_add_store (EMFolderTree *emft, CamelStore *store, const char *display_name);
-void em_folder_tree_remove_store (EMFolderTree *emft, CamelStore *store);
-
void em_folder_tree_set_selected (EMFolderTree *emft, const char *uri);
const char *em_folder_tree_get_selected_uri (EMFolderTree *emft);
const char *em_folder_tree_get_selected_path (EMFolderTree *emft);
diff --git a/mail/mail-component.c b/mail/mail-component.c
index c278e6217b..6f06889e81 100644
--- a/mail/mail-component.c
+++ b/mail/mail-component.c
@@ -77,7 +77,7 @@ static BonoboObjectClass *parent_class = NULL;
struct _MailComponentPrivate {
char *base_directory;
- EMFolderTree *emft;
+ EMFolderTreeModel *model;
MailAsyncEvent *async_event;
GHashTable *store_hash; /* display_name by store */
@@ -96,7 +96,7 @@ add_store (MailComponent *component, const char *name, CamelStore *store, CamelE
{
camel_object_ref (store);
g_hash_table_insert (component->priv->store_hash, store, g_strdup (name));
- em_folder_tree_add_store (component->priv->emft, store, name);
+ em_folder_tree_model_add_store (component->priv->model, store, name);
mail_note_store (store, NULL, NULL, NULL);
}
@@ -327,8 +327,8 @@ impl_createControls (PortableServer_Servant servant,
GtkWidget *tree_widget;
GtkWidget *view_widget;
- tree_widget = (GtkWidget *) priv->emft;
view_widget = em_folder_browser_new ();
+ tree_widget = (GtkWidget *) em_folder_tree_new_with_model (priv->model);
em_format_set_session ((EMFormat *) ((EMFolderView *) view_widget)->preview, session);
gtk_widget_show (tree_widget);
@@ -431,7 +431,7 @@ mail_component_init (MailComponent *component)
if (camel_mkdir (priv->base_directory, 0777) == -1 && errno != EEXIST)
abort ();
- priv->emft = (EMFolderTree *) em_folder_tree_new ();
+ priv->model = em_folder_tree_model_new ();
/* EPFIXME: Turn into an object? */
mail_session_init (priv->base_directory);
@@ -624,7 +624,7 @@ mail_component_remove_store (MailComponent *component, CamelStore *store)
being removed. ?? */
mail_note_store_remove (store);
- em_folder_tree_remove_store (priv->emft, store);
+ em_folder_tree_model_remove_store (priv->model, store);
mail_async_event_emit (priv->async_event, MAIL_ASYNC_THREAD, (MailAsyncFunc) store_disconnect, store, NULL, NULL);
}
@@ -675,12 +675,8 @@ mail_component_remove_folder (MailComponent *component, CamelStore *store, const
EMFolderTreeModel *
mail_component_get_tree_model (MailComponent *component)
{
- EMFolderTreeModel *model;
-
- model = em_folder_tree_get_model (component->priv->emft);
- g_object_ref (model);
-
- return model;
+ g_object_ref (component->priv->model);
+ return component->priv->model;
}
struct _CamelFolder *