diff options
author | Jeffrey Stedfast <fejj@ximian.com> | 2003-11-19 04:06:15 +0800 |
---|---|---|
committer | Jeffrey Stedfast <fejj@src.gnome.org> | 2003-11-19 04:06:15 +0800 |
commit | f0df568f6b1311bd139076d21be255879b391fde (patch) | |
tree | 6eff2db5ccd939da808cac46d0a04edc0895f155 /mail/em-folder-tree.c | |
parent | 8dcc0c8932ca8732ef423acc8a972a049e0091e7 (diff) | |
download | gsoc2013-evolution-f0df568f6b1311bd139076d21be255879b391fde.tar.gz gsoc2013-evolution-f0df568f6b1311bd139076d21be255879b391fde.tar.zst gsoc2013-evolution-f0df568f6b1311bd139076d21be255879b391fde.zip |
Queue the camel_store_get_folder_info() call in another thread.
2003-11-18 Jeffrey Stedfast <fejj@ximian.com>
* em-folder-tree.c (tree_row_expanded): Queue the
camel_store_get_folder_info() call in another thread.
(em_folder_tree_get_folder_info__got): Moved all the logic of
tree_row_expanded here.
svn path=/trunk/; revision=23426
Diffstat (limited to 'mail/em-folder-tree.c')
-rw-r--r-- | mail/em-folder-tree.c | 164 |
1 files changed, 115 insertions, 49 deletions
diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c index 9aa51ce1fa..a6867272a7 100644 --- a/mail/em-folder-tree.c +++ b/mail/em-folder-tree.c @@ -355,6 +355,9 @@ em_folder_tree_destroy (GtkObject *obj) priv->ddd = 0; } + priv->treeview = NULL; + priv->model = NULL; + GTK_OBJECT_CLASS (parent_class)->destroy (obj); } @@ -379,8 +382,6 @@ folder_tree_new (EMFolderTreeModel *model) renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer, TRUE); gtk_tree_view_column_set_cell_data_func (column, renderer, render_display_name, NULL, NULL); - /*gtk_tree_view_insert_column_with_attributes ((GtkTreeView *) tree, -1, "", - renderer, "text", 0, NULL);*/ selection = gtk_tree_view_get_selection ((GtkTreeView *) tree); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); @@ -869,7 +870,7 @@ tree_store_set_folder_info (GtkTreeStore *model, GtkTreeIter *iter, GtkTreeIter sub; gboolean load; - load = (fi->flags & CAMEL_FOLDER_CHILDREN) && !(fi->flags & CAMEL_FOLDER_NOINFERIORS); + 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); @@ -934,80 +935,145 @@ dump_fi (CamelFolderInfo *fi, int depth) } #endif +struct _EMFolderTreeGetFolderInfo { + struct _mail_msg msg; + + /* input data */ + GtkTreeRowReference *root; + EMFolderTree *emft; + CamelStore *store; + char *top; + + /* output data */ + CamelFolderInfo *fi; +}; + static void -tree_row_expanded (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *tree_path, EMFolderTree *emft) +em_folder_tree_get_folder_info__get (struct _mail_msg *mm) { - /* FIXME: might be best to call get_folder_info in another thread and add the nodes to the treeview in the callback? */ - struct _EMFolderTreePrivate *priv = emft->priv; + struct _EMFolderTreeGetFolderInfo *m = (struct _EMFolderTreeGetFolderInfo *) mm; + guint32 flags = 0; + + if (camel_store_supports_subscriptions (m->store)) + flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED; + + m->fi = camel_store_get_folder_info (m->store, m->top, flags, &mm->ex); +} + +static void +em_folder_tree_get_folder_info__got (struct _mail_msg *mm) +{ + struct _EMFolderTreeGetFolderInfo *m = (struct _EMFolderTreeGetFolderInfo *) mm; + struct _EMFolderTreePrivate *priv = m->emft->priv; struct _EMFolderTreeModelStoreInfo *si; - CamelFolderInfo *fi, *child; - CamelStore *store; - CamelException ex; + GtkTreeIter root, iter; + CamelFolderInfo *fi; GtkTreeStore *model; - GtkTreeIter iter; + GtkTreePath *path; gboolean load; - char *path; - char *top; - - model = (GtkTreeStore *) gtk_tree_view_get_model (treeview); - gtk_tree_model_get ((GtkTreeModel *) model, root, - COL_STRING_FOLDER_PATH, &path, - COL_POINTER_CAMEL_STORE, &store, - COL_BOOL_LOAD_SUBDIRS, &load, - -1); - if (!load) + /* check that we haven't been destroyed */ + if (priv->treeview == NULL) return; - if (!(si = g_hash_table_lookup (priv->model->store_hash, store))) { - g_assert_not_reached (); + if (!(si = g_hash_table_lookup (priv->model->store_hash, m->store))) { + /* store has been removed in the interim - do nothing */ return; } - /* get the first child (which will be a dummy if we haven't loaded the child folders yet) */ - gtk_tree_model_iter_children ((GtkTreeModel *) model, &iter, root); + model = (GtkTreeStore *) gtk_tree_view_get_model (priv->treeview); - /* FIXME: this sucks ass, need to fix camel so that using path as @top will Just Work (tm) */ - /* NOTE: CamelImapStore will handle "" as toplevel, but CamelMboxStore wants NULL */ - if (!path || !strcmp (path, "/")) - top = NULL; - else - top = path + 1; + path = gtk_tree_row_reference_get_path (m->root); + gtk_tree_model_get_iter ((GtkTreeModel *) model, &root, path); + gtk_tree_path_free (path); - /* FIXME: are there any flags we want to pass when getting folder-info's? */ - camel_exception_init (&ex); - if (!(fi = camel_store_get_folder_info (store, top, 0, &ex))) { - /* FIXME: report error to user? or simply re-collapse node? or both? */ - g_warning ("can't get folder-info's for store '%s' at path='%s'", si->display_name, path); - gtk_tree_store_remove (model, &iter); - camel_exception_clear (&ex); + /* make sure we still need to load the tree subfolders... */ + gtk_tree_model_get ((GtkTreeModel *) model, &root, + COL_BOOL_LOAD_SUBDIRS, &load, + -1); + if (!load) return; - } + + /* get the first child (which will be a dummy node) */ + gtk_tree_model_iter_children ((GtkTreeModel *) model, &iter, &root); /* FIXME: camel is totally on crack here, @top's folder info * should be @fi and fi->child should be what we want to fill * our tree with... *sigh* */ - if (top && !strcmp (fi->full_name, top)) { - if (!(child = fi->child)) - child = fi->sibling; + if (m->top && !strcmp (m->fi->full_name, m->top)) { + if (!(fi = m->fi->child)) + fi = m->fi->sibling; } else - child = fi; + fi = m->fi; - if (child == NULL) { + if (fi == NULL) { /* no children afterall... remove the "Loading..." placeholder node */ gtk_tree_store_remove (model, &iter); } else { do { - tree_store_set_folder_info (model, &iter, priv, si, child); + tree_store_set_folder_info (model, &iter, priv, si, fi); - if ((child = child->sibling) != NULL) - gtk_tree_store_append (model, &iter, root); - } while (child != NULL); + if ((fi = fi->sibling) != NULL) + gtk_tree_store_append (model, &iter, &root); + } while (fi != NULL); } - gtk_tree_store_set (model, root, COL_BOOL_LOAD_SUBDIRS, FALSE, -1); + gtk_tree_store_set (model, &root, COL_BOOL_LOAD_SUBDIRS, FALSE, -1); +} + +static void +em_folder_tree_get_folder_info__free (struct _mail_msg *mm) +{ + struct _EMFolderTreeGetFolderInfo *m = (struct _EMFolderTreeGetFolderInfo *) mm; - camel_store_free_folder_info (store, fi); + camel_store_free_folder_info (m->store, m->fi); + + gtk_tree_row_reference_free (m->root); + /*g_object_unref (m->emft);*/ + camel_object_unref (m->store); + g_free (m->top); +} + +static struct _mail_msg_op get_folder_info_op = { + NULL, + em_folder_tree_get_folder_info__get, + em_folder_tree_get_folder_info__got, + em_folder_tree_get_folder_info__free, +}; + +static void +tree_row_expanded (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *tree_path, EMFolderTree *emft) +{ + struct _EMFolderTreeGetFolderInfo *m; + GtkTreeModel *model; + CamelStore *store; + const char *top; + gboolean load; + char *path; + + model = gtk_tree_view_get_model (treeview); + + gtk_tree_model_get (model, root, + COL_STRING_FOLDER_PATH, &path, + COL_POINTER_CAMEL_STORE, &store, + COL_BOOL_LOAD_SUBDIRS, &load, + -1); + if (!load) + return; + + if (!path || !strcmp (path, "/")) + top = NULL; + else + top = path + 1; + + m = mail_msg_new (&get_folder_info_op, NULL, sizeof (struct _EMFolderTreeGetFolderInfo)); + m->root = gtk_tree_row_reference_new (model, tree_path); + camel_object_ref (store); + m->store = store; + m->emft = emft; + m->top = g_strdup (top); + + e_thread_put (mail_thread_new, (EMsg *) m); } |