diff console/libgnt/gnttree.c @ 14105:eaf7f35635bc

[gaim-migrate @ 16739] Allow autojoining chat rooms. Sort the buddies in the buddylist, and the plugins in the plugin list. committer: Tailor Script <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Sun, 13 Aug 2006 23:30:19 +0000
parents ae4cbed1b309
children c0ee28af3ca2
line wrap: on
line diff
--- a/console/libgnt/gnttree.c	Sun Aug 13 08:41:07 2006 +0000
+++ b/console/libgnt/gnttree.c	Sun Aug 13 23:30:19 2006 +0000
@@ -249,7 +249,10 @@
 	int start;
 	GntWidget *widget = GNT_WIDGET(tree);
 	GntTreeRow *row;
-	int pos;
+	int pos, up, down, nr;
+
+	if (!GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_MAPPED))
+		return;
 
 	if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))
 		pos = 0;
@@ -288,6 +291,21 @@
 		start = 2;
 	}
 
+	nr = widget->priv.height - pos * 2 - start - 1;
+	tree->bottom = get_next_n_opt(tree->top, nr, &down);
+	if (down < nr)
+	{
+		tree->top = get_prev_n(tree->bottom, nr);
+		if (tree->top == NULL)
+			tree->top = tree->root;
+	}
+
+	up = get_distance(tree->top, tree->current);
+	if (up < 0)
+		tree->top = tree->current;
+	else if (up >= widget->priv.height - pos)
+		tree->top = get_prev_n(tree->current, nr);
+
 	row = tree->top;
 	for (start = start + pos; row && start < widget->priv.height - pos;
 				start++, row = get_next(row))
@@ -379,8 +397,13 @@
 static void
 gnt_tree_map(GntWidget *widget)
 {
+	GntTree *tree = GNT_TREE(widget);
 	if (widget->priv.width == 0 || widget->priv.height == 0)
+	{
 		gnt_widget_size_request(widget);
+	}
+	tree->top = tree->root;
+	tree->current = tree->root;
 	DEBUG;
 }
 
@@ -616,12 +639,48 @@
 	g_signal_emit(tree, signals[SIG_SCROLLED], 0, count);
 }
 
+static gpointer
+find_position(GntTree *tree, gpointer key, gpointer parent)
+{
+	GntTreeRow *row;
+
+	if (tree->compare == NULL)
+		return NULL;
+
+	if (parent == NULL)
+		row = tree->root;
+	else
+		row = g_hash_table_lookup(tree->hash, parent);
+
+	if (!row)
+		return NULL;
+
+	if (parent)
+		row = row->child;
+
+	while (row)
+	{
+		if (tree->compare(key, row->key) < 0)
+			return (row->prev ? row->prev->key : NULL);
+		if (row->next)
+			row = row->next;
+		else
+			return row->key;
+	}
+	return NULL;
+}
+
 GntTreeRow *gnt_tree_add_row_after(GntTree *tree, void *key, GntTreeRow *row, void *parent, void *bigbro)
 {
 	GntTreeRow *pr = NULL;
 
 	g_hash_table_replace(tree->hash, key, row);
 
+	if (bigbro == NULL && tree->compare)
+	{
+		bigbro = find_position(tree, key, parent);
+	}
+
 	if (tree->root == NULL)
 	{
 		tree->root = row;
@@ -663,12 +722,10 @@
 		if (pr == NULL)
 		{
 			GntTreeRow *r = tree->root;
-			while (r->next)
-				r = r->next;
-			r->next = row;
-			row->prev = r;
-
-			tree->list = g_list_append(tree->list, key);
+			row->next = r;
+			if (r) r->prev = row;
+			tree->root = row;
+			tree->list = g_list_prepend(tree->list, key);
 		}
 		else
 		{
@@ -679,12 +736,32 @@
 	row->key = key;
 	row->data = NULL;
 
-	if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_MAPPED))
-		redraw_tree(tree);
+	redraw_tree(tree);
 
 	return row;
 }
 
+GntTreeRow *gnt_tree_add_row_last(GntTree *tree, void *key, GntTreeRow *row, void *parent)
+{
+	GntTreeRow *pr = NULL, *br = NULL;
+
+	if (parent)
+		pr = g_hash_table_lookup(tree->hash, parent);
+
+	if (pr)
+		br = pr->child;
+	else
+		br = tree->root;
+
+	if (br)
+	{
+		while (br->next)
+			br = br->next;
+	}
+
+	return gnt_tree_add_row_after(tree, key, row, parent, br ? br->key : NULL);
+}
+
 gpointer gnt_tree_get_selection_data(GntTree *tree)
 {
 	if (tree->current)
@@ -954,3 +1031,8 @@
 	tree->show_title = set;
 }
 
+void gnt_tree_set_compare_func(GntTree *tree, GCompareFunc func)
+{
+	tree->compare = func;
+}
+