Commit 740ee8ef authored by Havoc Pennington's avatar Havoc Pennington Committed by Havoc Pennington

handle case where sibling == iter (gtk_tree_store_insert_after): handle

2001-01-10  Havoc Pennington  <hp@redhat.com>

	* gtk/gtktreestore.c (gtk_tree_store_insert_before): handle case
	where sibling == iter
	(gtk_tree_store_insert_after): handle sibling == iter
	(gtk_tree_store_prepend): remove stamp checks
	(gtk_tree_store_insert_before): ditto
	(gtk_tree_store_append): ditto
	(gtk_tree_store_get_path): ditto
	(gtk_tree_store_get_value): ditto
	(gtk_tree_store_iter_has_child): ditto
	(gtk_tree_store_iter_n_children): ditto
	(gtk_tree_store_iter_nth_child): ditto
	(gtk_tree_store_insert_after): ditto
	(gtk_tree_store_is_ancestor): ditto
	(gtk_tree_store_iter_depth): ditto
	(gtk_tree_store_insert_before): assert that sibling's parent is
	the same as the passed-in parent
	(gtk_tree_store_insert_after): assert that sibling's parent is
	the same as the passed-in parent


	* gtk/gtktreemodel.c (gtk_tree_model_get_first): new convenience
	function to get the first iterator in a model

	* gtk/gtktreestore.c (gtk_tree_store_get_root_iter): remove,
	conventionally the "root" in this sense is just NULL afaict.

	* gtk/gtkliststore.c (gtk_list_store_insert_before): handle case
	where sibling == iter
	(gtk_list_store_insert_after): handle case where sibling == iter

	* tests/testtreeview.c (run_automated_tests): fairly lame basic
	automated tests for ListStore, TreeStore

        * gtk/gtkliststore.c (gtk_list_store_remove): update tail pointer
	(gtk_list_store_insert): update tail pointer, and fix it to work
	(gtk_list_store_insert_before): update tail pointer, and fix it to work
	(gtk_list_store_append): use tail to be faster
	(gtk_list_store_prepend): fix it, update tail pointer
	(gtk_list_store_insert_after): fix it, update tail pointer

	* gtk/gtkliststore.h (struct _GtkListStore): add tail pointer for
	the list
parent 85267e92
2001-01-10 Havoc Pennington <hp@redhat.com>
* gtk/gtktreestore.c (gtk_tree_store_insert_before): handle case
where sibling == iter
(gtk_tree_store_insert_after): handle sibling == iter
(gtk_tree_store_prepend): remove stamp checks
(gtk_tree_store_insert_before): ditto
(gtk_tree_store_append): ditto
(gtk_tree_store_get_path): ditto
(gtk_tree_store_get_value): ditto
(gtk_tree_store_iter_has_child): ditto
(gtk_tree_store_iter_n_children): ditto
(gtk_tree_store_iter_nth_child): ditto
(gtk_tree_store_insert_after): ditto
(gtk_tree_store_is_ancestor): ditto
(gtk_tree_store_iter_depth): ditto
(gtk_tree_store_insert_before): assert that sibling's parent is
the same as the passed-in parent
(gtk_tree_store_insert_after): assert that sibling's parent is
the same as the passed-in parent
* gtk/gtktreemodel.c (gtk_tree_model_get_first): new convenience
function to get the first iterator in a model
* gtk/gtktreestore.c (gtk_tree_store_get_root_iter): remove,
conventionally the "root" in this sense is just NULL afaict.
* gtk/gtkliststore.c (gtk_list_store_insert_before): handle case
where sibling == iter
(gtk_list_store_insert_after): handle case where sibling == iter
* tests/testtreeview.c (run_automated_tests): fairly lame basic
automated tests for ListStore, TreeStore
* gtk/gtkliststore.c (gtk_list_store_remove): update tail pointer
(gtk_list_store_insert): update tail pointer, and fix it to work
(gtk_list_store_insert_before): update tail pointer, and fix it to work
(gtk_list_store_append): use tail to be faster
(gtk_list_store_prepend): fix it, update tail pointer
(gtk_list_store_insert_after): fix it, update tail pointer
* gtk/gtkliststore.h (struct _GtkListStore): add tail pointer for
the list
2001-01-09 Havoc Pennington <hp@redhat.com> 2001-01-09 Havoc Pennington <hp@redhat.com>
* gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout * gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout
......
2001-01-10 Havoc Pennington <hp@redhat.com>
* gtk/gtktreestore.c (gtk_tree_store_insert_before): handle case
where sibling == iter
(gtk_tree_store_insert_after): handle sibling == iter
(gtk_tree_store_prepend): remove stamp checks
(gtk_tree_store_insert_before): ditto
(gtk_tree_store_append): ditto
(gtk_tree_store_get_path): ditto
(gtk_tree_store_get_value): ditto
(gtk_tree_store_iter_has_child): ditto
(gtk_tree_store_iter_n_children): ditto
(gtk_tree_store_iter_nth_child): ditto
(gtk_tree_store_insert_after): ditto
(gtk_tree_store_is_ancestor): ditto
(gtk_tree_store_iter_depth): ditto
(gtk_tree_store_insert_before): assert that sibling's parent is
the same as the passed-in parent
(gtk_tree_store_insert_after): assert that sibling's parent is
the same as the passed-in parent
* gtk/gtktreemodel.c (gtk_tree_model_get_first): new convenience
function to get the first iterator in a model
* gtk/gtktreestore.c (gtk_tree_store_get_root_iter): remove,
conventionally the "root" in this sense is just NULL afaict.
* gtk/gtkliststore.c (gtk_list_store_insert_before): handle case
where sibling == iter
(gtk_list_store_insert_after): handle case where sibling == iter
* tests/testtreeview.c (run_automated_tests): fairly lame basic
automated tests for ListStore, TreeStore
* gtk/gtkliststore.c (gtk_list_store_remove): update tail pointer
(gtk_list_store_insert): update tail pointer, and fix it to work
(gtk_list_store_insert_before): update tail pointer, and fix it to work
(gtk_list_store_append): use tail to be faster
(gtk_list_store_prepend): fix it, update tail pointer
(gtk_list_store_insert_after): fix it, update tail pointer
* gtk/gtkliststore.h (struct _GtkListStore): add tail pointer for
the list
2001-01-09 Havoc Pennington <hp@redhat.com> 2001-01-09 Havoc Pennington <hp@redhat.com>
* gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout * gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout
......
2001-01-10 Havoc Pennington <hp@redhat.com>
* gtk/gtktreestore.c (gtk_tree_store_insert_before): handle case
where sibling == iter
(gtk_tree_store_insert_after): handle sibling == iter
(gtk_tree_store_prepend): remove stamp checks
(gtk_tree_store_insert_before): ditto
(gtk_tree_store_append): ditto
(gtk_tree_store_get_path): ditto
(gtk_tree_store_get_value): ditto
(gtk_tree_store_iter_has_child): ditto
(gtk_tree_store_iter_n_children): ditto
(gtk_tree_store_iter_nth_child): ditto
(gtk_tree_store_insert_after): ditto
(gtk_tree_store_is_ancestor): ditto
(gtk_tree_store_iter_depth): ditto
(gtk_tree_store_insert_before): assert that sibling's parent is
the same as the passed-in parent
(gtk_tree_store_insert_after): assert that sibling's parent is
the same as the passed-in parent
* gtk/gtktreemodel.c (gtk_tree_model_get_first): new convenience
function to get the first iterator in a model
* gtk/gtktreestore.c (gtk_tree_store_get_root_iter): remove,
conventionally the "root" in this sense is just NULL afaict.
* gtk/gtkliststore.c (gtk_list_store_insert_before): handle case
where sibling == iter
(gtk_list_store_insert_after): handle case where sibling == iter
* tests/testtreeview.c (run_automated_tests): fairly lame basic
automated tests for ListStore, TreeStore
* gtk/gtkliststore.c (gtk_list_store_remove): update tail pointer
(gtk_list_store_insert): update tail pointer, and fix it to work
(gtk_list_store_insert_before): update tail pointer, and fix it to work
(gtk_list_store_append): use tail to be faster
(gtk_list_store_prepend): fix it, update tail pointer
(gtk_list_store_insert_after): fix it, update tail pointer
* gtk/gtkliststore.h (struct _GtkListStore): add tail pointer for
the list
2001-01-09 Havoc Pennington <hp@redhat.com> 2001-01-09 Havoc Pennington <hp@redhat.com>
* gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout * gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout
......
2001-01-10 Havoc Pennington <hp@redhat.com>
* gtk/gtktreestore.c (gtk_tree_store_insert_before): handle case
where sibling == iter
(gtk_tree_store_insert_after): handle sibling == iter
(gtk_tree_store_prepend): remove stamp checks
(gtk_tree_store_insert_before): ditto
(gtk_tree_store_append): ditto
(gtk_tree_store_get_path): ditto
(gtk_tree_store_get_value): ditto
(gtk_tree_store_iter_has_child): ditto
(gtk_tree_store_iter_n_children): ditto
(gtk_tree_store_iter_nth_child): ditto
(gtk_tree_store_insert_after): ditto
(gtk_tree_store_is_ancestor): ditto
(gtk_tree_store_iter_depth): ditto
(gtk_tree_store_insert_before): assert that sibling's parent is
the same as the passed-in parent
(gtk_tree_store_insert_after): assert that sibling's parent is
the same as the passed-in parent
* gtk/gtktreemodel.c (gtk_tree_model_get_first): new convenience
function to get the first iterator in a model
* gtk/gtktreestore.c (gtk_tree_store_get_root_iter): remove,
conventionally the "root" in this sense is just NULL afaict.
* gtk/gtkliststore.c (gtk_list_store_insert_before): handle case
where sibling == iter
(gtk_list_store_insert_after): handle case where sibling == iter
* tests/testtreeview.c (run_automated_tests): fairly lame basic
automated tests for ListStore, TreeStore
* gtk/gtkliststore.c (gtk_list_store_remove): update tail pointer
(gtk_list_store_insert): update tail pointer, and fix it to work
(gtk_list_store_insert_before): update tail pointer, and fix it to work
(gtk_list_store_append): use tail to be faster
(gtk_list_store_prepend): fix it, update tail pointer
(gtk_list_store_insert_after): fix it, update tail pointer
* gtk/gtkliststore.h (struct _GtkListStore): add tail pointer for
the list
2001-01-09 Havoc Pennington <hp@redhat.com> 2001-01-09 Havoc Pennington <hp@redhat.com>
* gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout * gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout
......
2001-01-10 Havoc Pennington <hp@redhat.com>
* gtk/gtktreestore.c (gtk_tree_store_insert_before): handle case
where sibling == iter
(gtk_tree_store_insert_after): handle sibling == iter
(gtk_tree_store_prepend): remove stamp checks
(gtk_tree_store_insert_before): ditto
(gtk_tree_store_append): ditto
(gtk_tree_store_get_path): ditto
(gtk_tree_store_get_value): ditto
(gtk_tree_store_iter_has_child): ditto
(gtk_tree_store_iter_n_children): ditto
(gtk_tree_store_iter_nth_child): ditto
(gtk_tree_store_insert_after): ditto
(gtk_tree_store_is_ancestor): ditto
(gtk_tree_store_iter_depth): ditto
(gtk_tree_store_insert_before): assert that sibling's parent is
the same as the passed-in parent
(gtk_tree_store_insert_after): assert that sibling's parent is
the same as the passed-in parent
* gtk/gtktreemodel.c (gtk_tree_model_get_first): new convenience
function to get the first iterator in a model
* gtk/gtktreestore.c (gtk_tree_store_get_root_iter): remove,
conventionally the "root" in this sense is just NULL afaict.
* gtk/gtkliststore.c (gtk_list_store_insert_before): handle case
where sibling == iter
(gtk_list_store_insert_after): handle case where sibling == iter
* tests/testtreeview.c (run_automated_tests): fairly lame basic
automated tests for ListStore, TreeStore
* gtk/gtkliststore.c (gtk_list_store_remove): update tail pointer
(gtk_list_store_insert): update tail pointer, and fix it to work
(gtk_list_store_insert_before): update tail pointer, and fix it to work
(gtk_list_store_append): use tail to be faster
(gtk_list_store_prepend): fix it, update tail pointer
(gtk_list_store_insert_after): fix it, update tail pointer
* gtk/gtkliststore.h (struct _GtkListStore): add tail pointer for
the list
2001-01-09 Havoc Pennington <hp@redhat.com> 2001-01-09 Havoc Pennington <hp@redhat.com>
* gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout * gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout
......
2001-01-10 Havoc Pennington <hp@redhat.com>
* gtk/gtktreestore.c (gtk_tree_store_insert_before): handle case
where sibling == iter
(gtk_tree_store_insert_after): handle sibling == iter
(gtk_tree_store_prepend): remove stamp checks
(gtk_tree_store_insert_before): ditto
(gtk_tree_store_append): ditto
(gtk_tree_store_get_path): ditto
(gtk_tree_store_get_value): ditto
(gtk_tree_store_iter_has_child): ditto
(gtk_tree_store_iter_n_children): ditto
(gtk_tree_store_iter_nth_child): ditto
(gtk_tree_store_insert_after): ditto
(gtk_tree_store_is_ancestor): ditto
(gtk_tree_store_iter_depth): ditto
(gtk_tree_store_insert_before): assert that sibling's parent is
the same as the passed-in parent
(gtk_tree_store_insert_after): assert that sibling's parent is
the same as the passed-in parent
* gtk/gtktreemodel.c (gtk_tree_model_get_first): new convenience
function to get the first iterator in a model
* gtk/gtktreestore.c (gtk_tree_store_get_root_iter): remove,
conventionally the "root" in this sense is just NULL afaict.
* gtk/gtkliststore.c (gtk_list_store_insert_before): handle case
where sibling == iter
(gtk_list_store_insert_after): handle case where sibling == iter
* tests/testtreeview.c (run_automated_tests): fairly lame basic
automated tests for ListStore, TreeStore
* gtk/gtkliststore.c (gtk_list_store_remove): update tail pointer
(gtk_list_store_insert): update tail pointer, and fix it to work
(gtk_list_store_insert_before): update tail pointer, and fix it to work
(gtk_list_store_append): use tail to be faster
(gtk_list_store_prepend): fix it, update tail pointer
(gtk_list_store_insert_after): fix it, update tail pointer
* gtk/gtkliststore.h (struct _GtkListStore): add tail pointer for
the list
2001-01-09 Havoc Pennington <hp@redhat.com> 2001-01-09 Havoc Pennington <hp@redhat.com>
* gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout * gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout
......
2001-01-10 Havoc Pennington <hp@redhat.com>
* gtk/gtktreestore.c (gtk_tree_store_insert_before): handle case
where sibling == iter
(gtk_tree_store_insert_after): handle sibling == iter
(gtk_tree_store_prepend): remove stamp checks
(gtk_tree_store_insert_before): ditto
(gtk_tree_store_append): ditto
(gtk_tree_store_get_path): ditto
(gtk_tree_store_get_value): ditto
(gtk_tree_store_iter_has_child): ditto
(gtk_tree_store_iter_n_children): ditto
(gtk_tree_store_iter_nth_child): ditto
(gtk_tree_store_insert_after): ditto
(gtk_tree_store_is_ancestor): ditto
(gtk_tree_store_iter_depth): ditto
(gtk_tree_store_insert_before): assert that sibling's parent is
the same as the passed-in parent
(gtk_tree_store_insert_after): assert that sibling's parent is
the same as the passed-in parent
* gtk/gtktreemodel.c (gtk_tree_model_get_first): new convenience
function to get the first iterator in a model
* gtk/gtktreestore.c (gtk_tree_store_get_root_iter): remove,
conventionally the "root" in this sense is just NULL afaict.
* gtk/gtkliststore.c (gtk_list_store_insert_before): handle case
where sibling == iter
(gtk_list_store_insert_after): handle case where sibling == iter
* tests/testtreeview.c (run_automated_tests): fairly lame basic
automated tests for ListStore, TreeStore
* gtk/gtkliststore.c (gtk_list_store_remove): update tail pointer
(gtk_list_store_insert): update tail pointer, and fix it to work
(gtk_list_store_insert_before): update tail pointer, and fix it to work
(gtk_list_store_append): use tail to be faster
(gtk_list_store_prepend): fix it, update tail pointer
(gtk_list_store_insert_after): fix it, update tail pointer
* gtk/gtkliststore.h (struct _GtkListStore): add tail pointer for
the list
2001-01-09 Havoc Pennington <hp@redhat.com> 2001-01-09 Havoc Pennington <hp@redhat.com>
* gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout * gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout
......
...@@ -171,6 +171,7 @@ static void ...@@ -171,6 +171,7 @@ static void
gtk_list_store_init (GtkListStore *list_store) gtk_list_store_init (GtkListStore *list_store)
{ {
list_store->root = NULL; list_store->root = NULL;
list_store->tail = NULL;
list_store->stamp = g_random_int (); list_store->stamp = g_random_int ();
} }
...@@ -612,6 +613,39 @@ gtk_list_store_get (GtkListStore *list_store, ...@@ -612,6 +613,39 @@ gtk_list_store_get (GtkListStore *list_store,
va_end (var_args); va_end (var_args);
} }
static GSList*
remove_link_saving_prev (GSList *list,
GSList *link,
GSList **prevp)
{
GSList *tmp;
GSList *prev;
prev = NULL;
tmp = list;
while (tmp)
{
if (tmp == link)
{
if (prev)
prev->next = tmp->next;
if (list == tmp)
list = list->next;
tmp->next = NULL;
break;
}
prev = tmp;
tmp = tmp->next;
}
*prevp = prev;
return list;
}
void void
gtk_list_store_remove (GtkListStore *list_store, gtk_list_store_remove (GtkListStore *list_store,
GtkTreeIter *iter) GtkTreeIter *iter)
...@@ -620,14 +654,25 @@ gtk_list_store_remove (GtkListStore *list_store, ...@@ -620,14 +654,25 @@ gtk_list_store_remove (GtkListStore *list_store,
g_return_if_fail (list_store != NULL); g_return_if_fail (list_store != NULL);
g_return_if_fail (GTK_IS_LIST_STORE (list_store)); g_return_if_fail (GTK_IS_LIST_STORE (list_store));
g_return_if_fail (iter->user_data != NULL);
if (G_SLIST (iter->user_data)->data) if (G_SLIST (iter->user_data)->data)
_gtk_tree_data_list_free ((GtkTreeDataList *) G_SLIST (iter->user_data)->data, _gtk_tree_data_list_free ((GtkTreeDataList *) G_SLIST (iter->user_data)->data,
list_store->column_headers); list_store->column_headers);
path = gtk_list_store_get_path (GTK_TREE_MODEL (list_store), iter); path = gtk_list_store_get_path (GTK_TREE_MODEL (list_store), iter);
list_store->root = g_slist_remove_link (G_SLIST (list_store->root),
G_SLIST (iter->user_data)); {
GSList *prev = NULL;
list_store->root = remove_link_saving_prev (G_SLIST (list_store->root),
G_SLIST (iter->user_data),
&prev);
if (iter->user_data == list_store->tail)
list_store->tail = prev;
}
list_store->stamp ++; list_store->stamp ++;
gtk_signal_emit_by_name (GTK_OBJECT (list_store), gtk_signal_emit_by_name (GTK_OBJECT (list_store),
"deleted", "deleted",
...@@ -635,6 +680,23 @@ gtk_list_store_remove (GtkListStore *list_store, ...@@ -635,6 +680,23 @@ gtk_list_store_remove (GtkListStore *list_store,
gtk_tree_path_free (path); gtk_tree_path_free (path);
} }
static void
insert_after (GtkListStore *list_store,
GSList *sibling,
GSList *new_list)
{
g_return_if_fail (sibling != NULL);
g_return_if_fail (new_list != NULL);
/* insert new node after list */
new_list->next = sibling->next;
sibling->next = new_list;
/* if list was the tail, the new node is the new tail */
if (sibling == list_store->tail)
list_store->tail = new_list;
}
void void
gtk_list_store_insert (GtkListStore *list_store, gtk_list_store_insert (GtkListStore *list_store,
GtkTreeIter *iter, GtkTreeIter *iter,
...@@ -642,11 +704,12 @@ gtk_list_store_insert (GtkListStore *list_store, ...@@ -642,11 +704,12 @@ gtk_list_store_insert (GtkListStore *list_store,
{ {
GSList *list; GSList *list;
GtkTreePath *path; GtkTreePath *path;
GSList *new_list;
g_return_if_fail (list_store != NULL); g_return_if_fail (list_store != NULL);
g_return_if_fail (GTK_IS_LIST_STORE (list_store)); g_return_if_fail (GTK_IS_LIST_STORE (list_store));
g_return_if_fail (iter != NULL); g_return_if_fail (iter != NULL);
g_return_if_fail (position < 0); g_return_if_fail (position >= 0);
if (position == 0) if (position == 0)
{ {
...@@ -654,15 +717,21 @@ gtk_list_store_insert (GtkListStore *list_store, ...@@ -654,15 +717,21 @@ gtk_list_store_insert (GtkListStore *list_store,
return; return;
} }
iter->stamp = list_store->stamp; new_list = g_slist_alloc ();
iter->user_data = g_slist_alloc ();
list = g_slist_nth (G_SLIST (list_store->root), position - 1); list = g_slist_nth (G_SLIST (list_store->root), position - 1);
if (list)
if (list == NULL)
{ {
G_SLIST (iter->user_data)->next = list->next; g_warning ("%s: position %d is off the end of the list\n", G_STRLOC, position);
list->next = G_SLIST (iter->user_data)->next; return;
} }
insert_after (list_store, list, new_list);
iter->stamp = list_store->stamp;
iter->user_data = new_list;
path = gtk_tree_path_new (); path = gtk_tree_path_new ();
gtk_tree_path_append_index (path, position); gtk_tree_path_append_index (path, position);
gtk_signal_emit_by_name (GTK_OBJECT (list_store), gtk_signal_emit_by_name (GTK_OBJECT (list_store),
...@@ -677,22 +746,20 @@ gtk_list_store_insert_before (GtkListStore *list_store, ...@@ -677,22 +746,20 @@ gtk_list_store_insert_before (GtkListStore *list_store,
GtkTreeIter *sibling) GtkTreeIter *sibling)
{ {
GtkTreePath *path; GtkTreePath *path;
GSList *list, *prev; GSList *list, *prev, *new_list;
gint i = 0; gint i = 0;
g_return_if_fail (list_store != NULL); g_return_if_fail (list_store != NULL);
g_return_if_fail (GTK_IS_LIST_STORE (list_store)); g_return_if_fail (GTK_IS_LIST_STORE (list_store));
g_return_if_fail (iter != NULL); g_return_if_fail (iter != NULL);
g_return_if_fail (G_SLIST (iter)->next == NULL);
if (sibling == NULL) if (sibling == NULL)
{ {
gtk_list_store_append (list_store, iter); gtk_list_store_append (list_store, iter);
return; return;
} }
iter->stamp = list_store->stamp; new_list = g_slist_alloc ();
iter->user_data = g_slist_alloc ();
prev = list = list_store->root; prev = list = list_store->root;
while (list && list != sibling->user_data) while (list && list != sibling->user_data)
...@@ -701,17 +768,35 @@ gtk_list_store_insert_before (GtkListStore *list_store, ...@@ -701,17 +768,35 @@ gtk_list_store_insert_before (GtkListStore *list_store,
list = list->next; list = list->next;
i++; i++;
} }
if (list != sibling->user_data)
{
g_warning ("%s: sibling iterator invalid? not found in the list", G_STRLOC);
return;
}
/* if there are no nodes, we become the list tail, otherwise we
* are inserting before any existing nodes so we can't change
* the tail
*/
if (list_store->root == NULL)
list_store->tail = new_list;
if (prev) if (prev)
{ {
prev->next = iter->user_data; new_list->next = prev->next;
prev->next = new_list;
} }
else else
{ {
G_SLIST (iter->user_data)->next = list_store->root; new_list->next = list_store->root;
list_store->root = iter->user_data; list_store->root = new_list;
} }
iter->stamp = list_store->stamp;
iter->user_data = new_list;
path = gtk_tree_path_new (); path = gtk_tree_path_new ();
gtk_tree_path_append_index (path, i); gtk_tree_path_append_index (path, i);
gtk_signal_emit_by_name (GTK_OBJECT (list_store), gtk_signal_emit_by_name (GTK_OBJECT (list_store),
...@@ -726,12 +811,12 @@ gtk_list_store_insert_after (GtkListStore *list_store, ...@@ -726,12 +811,12 @@ gtk_list_store_insert_after (GtkListStore *list_store,
GtkTreeIter *sibling) GtkTreeIter *sibling)
{ {
GtkTreePath *path; GtkTreePath *path;
GSList *list; GSList *list, *new_list;
gint i = 0; gint i = 0;
g_return_if_fail (list_store != NULL); g_return_if_fail (list_store != NULL);
g_return_if_fail (GTK_IS_LIST_STORE (list_store)); g_return_if_fail (GTK_IS_LIST_STORE (list_store));
g_return_if_fail (iter == NULL); g_return_if_fail (iter != NULL);
if (sibling) if (sibling)
g_return_if_fail (sibling->stamp == list_store->stamp); g_return_if_fail (sibling->stamp == list_store->stamp);
...@@ -744,14 +829,15 @@ gtk_list_store_insert_after (GtkListStore *list_store, ...@@ -744,14 +829,15 @@ gtk_list_store_insert_after (GtkListStore *list_store,
for (list = list_store->root; list && list != sibling->user_data; list = list->next) for (list = list_store->root; list && list != sibling->user_data; list = list->next)
i++; i++;
g_return_if_fail (list != NULL); g_return_if_fail (list == sibling->user_data);
iter->stamp = list_store->stamp; new_list = g_slist_alloc ();
iter->user_data = g_slist_alloc ();
G_SLIST (iter->user_data)->next = G_SLIST (sibling->user_data)->next;
G_SLIST (sibling)->next = G_SLIST (iter);
insert_after (list_store, list, new_list);
iter->stamp = list_store->stamp;
iter->user_data = new_list;
path = gtk_tree_path_new (); path = gtk_tree_path_new ();
gtk_tree_path_append_index (path, i); gtk_tree_path_append_index (path, i);
gtk_signal_emit_by_name (GTK_OBJECT (list_store), gtk_signal_emit_by_name (GTK_OBJECT (list_store),
...@@ -773,6 +859,9 @@ gtk_list_store_prepend (GtkListStore *list_store, ...@@ -773,6 +859,9 @@ gtk_list_store_prepend (GtkListStore *list_store,
iter->stamp = list_store->stamp; iter->stamp = list_store->stamp;
iter->user_data = g_slist_alloc (); iter->user_data = g_slist_alloc ();
if (list_store->root == NULL)
list_store->tail = iter->user_data;
G_SLIST (iter->user_data)->next = G_SLIST (list_store->root); G_SLIST (iter->user_data)->next = G_SLIST (list_store->root);
list_store->root = iter->user_data; list_store->root = iter->user_data;
...@@ -789,7 +878,6 @@ gtk_list_store_append (GtkListStore *list_store, ...@@ -789,7 +878,6 @@ gtk_list_store_append (GtkListStore *list_store,
GtkTreeIter *iter) GtkTreeIter *iter)
{ {
GtkTreePath *path; GtkTreePath *path;
GSList *list, *prev;
gint i = 0; gint i = 0;
g_return_if_fail (list_store != NULL); g_return_if_fail (list_store != NULL);
...@@ -799,19 +887,13 @@ gtk_list_store_append (GtkListStore *list_store, ...@@ -799,19 +887,13 @@ gtk_list_store_append (GtkListStore *list_store,
iter->stamp = list_store->stamp; iter->stamp = list_store->stamp;
iter->user_data = g_slist_alloc (); iter->user_data = g_slist_alloc ();
prev = list = list_store->root; if (list_store->tail)
while (list) list_store->tail->next = iter->user_data;
{
prev = list;
list = list->next;
i++;
}
if (prev)
prev->next = iter->user_data;
else else
list_store->root = iter->user_data; list_store->root = iter->user_data;
list_store->tail = iter->user_data;
path = gtk_tree_path_new (); path = gtk_tree_path_new ();
gtk_tree_path_append_index (path, i); gtk_tree_path_append_index (path, i);
gtk_signal_emit_by_name (GTK_OBJECT (list_store), gtk_signal_emit_by_name (GTK_OBJECT (list_store),
......
...@@ -42,6 +42,7 @@ struct _GtkListStore ...@@ -42,6 +42,7 @@ struct _GtkListStore
/*< private >*/ /*< private >*/
gint stamp; gint stamp;
gpointer root; gpointer root;
GSList *tail;
gint n_columns; gint n_columns;
GType *column_headers; GType *column_headers;
}; };
......
...@@ -542,6 +542,36 @@ gtk_tree_model_get_iter (GtkTreeModel *tree_model, ...@@ -542,6 +542,36 @@ gtk_tree_model_get_iter (GtkTreeModel *tree_model,
return TRUE; return TRUE;
} }
/**
* gtk_tree_model_get_first:
* @tree_model: a #GtkTreeModel
* @iter: iterator to initialize
*
* Initialized @iter with the first iterator in the tree (the one at the
* root path) and returns %TRUE, or returns %FALSE if there are no
* iterable locations in the model (i.e. the tree is empty).
*
* Return value: %TRUE if @iter was initialized
**/
gboolean
gtk_tree_model_get_first (GtkTreeModel *tree_model,
GtkTreeIter *iter)
{
gboolean retval;
GtkTreePath *path;
g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);