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.c449
1 files changed, 3 insertions, 446 deletions
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)
{