⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gnttree.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	row = g_hash_table_lookup(tree->hash, key);	g_return_if_fail(row != NULL);	current = g_list_index(tree->list, key);	if (row->parent)		s = row->parent->child;	else		s = tree->root;	q = NULL;	while (s) {		if (tree->compare(row->key, s->key) < 0)			break;		q = s;		s = s->next;	}	/* Move row between q and s */	if (row == q || row == s)		return;	if (q == NULL) {		/* row becomes the first child of its parent */		row->prev->next = row->next;  /* row->prev cannot be NULL at this point */		if (row->next)			row->next->prev = row->prev;		if (row->parent)			row->parent->child = row;		else			tree->root = row;		row->next = s;		s->prev = row;  /* s cannot be NULL */		row->prev = NULL;		newp = g_list_index(tree->list, s) - 1;	} else {		if (row->prev) {			row->prev->next = row->next;		} else {			/* row was the first child of its parent */			if (row->parent)				row->parent->child = row->next;			else				tree->top = row->next;		}		if (row->next)			row->next->prev = row->prev;		q->next = row;		row->prev = q;		if (s)			s->prev = row;		row->next = s;		newp = g_list_index(tree->list, q) + 1;	}	tree->list = g_list_reposition_child(tree->list, current, newp);	redraw_tree(tree);}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);	row->tree = tree;	if (bigbro == NULL && tree->compare)	{		bigbro = find_position(tree, key, parent);	}	if (tree->root == NULL)	{		tree->root = row;		tree->list = g_list_prepend(tree->list, key);	}	else	{		int position = 0;		if (bigbro)		{			pr = g_hash_table_lookup(tree->hash, bigbro);			if (pr)			{				if (pr->next)	pr->next->prev = row;				row->next = pr->next;				row->prev = pr;				pr->next = row;				row->parent = pr->parent;				position = g_list_index(tree->list, bigbro);			}		}		if (pr == NULL && parent)			{			pr = g_hash_table_lookup(tree->hash, parent);			if (pr)			{				if (pr->child)	pr->child->prev = row;				row->next = pr->child;				pr->child = row;				row->parent = pr;				position = g_list_index(tree->list, parent);			}		}		if (pr == NULL)		{			GntTreeRow *r = tree->root;			row->next = r;			if (r) r->prev = row;			if (tree->current == tree->root)				tree->current = row;			tree->root = row;			tree->list = g_list_prepend(tree->list, key);		}		else		{			tree->list = g_list_insert(tree->list, key, position + 1);		}	}	row->key = key;	row->data = NULL;	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)		return tree->current->key;	/* XXX: perhaps we should just get rid of 'data' */	return NULL;}char *gnt_tree_get_selection_text(GntTree *tree){	if (tree->current)		return update_row_text(tree, tree->current);	return NULL;}GList *gnt_tree_get_selection_text_list(GntTree *tree){	GList *list = NULL, *iter;	int i;	if (!tree->current)		return NULL;	for (i = 0, iter = tree->current->columns; i < tree->ncol && iter;			i++, iter = iter->next)	{		GntTreeCol *col = iter->data;		list = g_list_append(list, g_strdup(col->text));	}	return list;}void gnt_tree_remove(GntTree *tree, gpointer key){	GntTreeRow *row = g_hash_table_lookup(tree->hash, key);	static int depth = 0; /* Only redraw after all child nodes are removed */	if (row)	{		gboolean redraw = FALSE;		if (row->child) {			depth++;			while (row->child) {				gnt_tree_remove(tree, row->child->key);			}			depth--;		}		if (get_distance(tree->top, row) >= 0 && get_distance(row, tree->bottom) >= 0)			redraw = TRUE;		/* Update root/top/current/bottom if necessary */		if (tree->root == row)			tree->root = get_next(row);		if (tree->top == row)		{			if (tree->top != tree->root)				tree->top = get_prev(row);			else				tree->top = get_next(row);		}		if (tree->current == row)		{			if (tree->current != tree->root)				tree->current = get_prev(row);			else				tree->current = get_next(row);			tree_selection_changed(tree, row, tree->current);		}		if (tree->bottom == row)		{			tree->bottom = get_prev(row);		}		/* Fix the links */		if (row->next)			row->next->prev = row->prev;		if (row->parent && row->parent->child == row)			row->parent->child = row->next;		if (row->prev)			row->prev->next = row->next;		g_hash_table_remove(tree->hash, key);		tree->list = g_list_remove(tree->list, key);		if (redraw && depth == 0)		{			redraw_tree(tree);		}	}}static gbooleanreturn_true(gpointer key, gpointer data, gpointer null){	return TRUE;}void gnt_tree_remove_all(GntTree *tree){	tree->root = NULL;	g_hash_table_foreach_remove(tree->hash, (GHRFunc)return_true, tree);	g_list_free(tree->list);	tree->list = NULL;	tree->current = tree->top = tree->bottom = NULL;}int gnt_tree_get_selection_visible_line(GntTree *tree){	return get_distance(tree->top, tree->current) +			!!(GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_NO_BORDER));}void gnt_tree_change_text(GntTree *tree, gpointer key, int colno, const char *text){	GntTreeRow *row;	GntTreeCol *col;	g_return_if_fail(colno < tree->ncol);		row = g_hash_table_lookup(tree->hash, key);	if (row)	{		col = g_list_nth_data(row->columns, colno);		g_free(col->text);		col->text = g_strdup(text ? text : "");		if (get_distance(tree->top, row) >= 0 && get_distance(row, tree->bottom) >= 0)			redraw_tree(tree);	}}GntTreeRow *gnt_tree_add_choice(GntTree *tree, void *key, GntTreeRow *row, void *parent, void *bigbro){	GntTreeRow *r;	r = g_hash_table_lookup(tree->hash, key);	g_return_val_if_fail(!r || !r->choice, NULL);	if (bigbro == NULL) {		if (tree->compare)			bigbro = find_position(tree, key, parent);		else {			r = g_hash_table_lookup(tree->hash, parent);			if (!r)				r = tree->root;			else				r = r->child;			if (r) {				while (r->next)					r = r->next;				bigbro = r->key;			} 		}	}	row = gnt_tree_add_row_after(tree, key, row, parent, bigbro);	row->choice = TRUE;	return row;}void gnt_tree_set_choice(GntTree *tree, void *key, gboolean set){	GntTreeRow *row = g_hash_table_lookup(tree->hash, key);	if (!row)		return;	g_return_if_fail(row->choice);	row->isselected = set;	redraw_tree(tree);}gboolean gnt_tree_get_choice(GntTree *tree, void *key){	GntTreeRow *row = g_hash_table_lookup(tree->hash, key);	if (!row)		return FALSE;	g_return_val_if_fail(row->choice, FALSE);	return row->isselected;}void gnt_tree_set_row_flags(GntTree *tree, void *key, GntTextFormatFlags flags){	GntTreeRow *row = g_hash_table_lookup(tree->hash, key);	if (!row || row->flags == flags)		return;	row->flags = flags;	redraw_tree(tree);	/* XXX: It shouldn't be necessary to redraw the whole darned tree */}void gnt_tree_set_selected(GntTree *tree , void *key){	int dist;	GntTreeRow *row = g_hash_table_lookup(tree->hash, key);	if (!row || row == tree->current)		return;	if (tree->top == NULL)		tree->top = row;	if (tree->bottom == NULL)		tree->bottom = row;	tree->current = row;	if ((dist = get_distance(tree->current, tree->bottom)) < 0)		gnt_tree_scroll(tree, -dist);	else if ((dist = get_distance(tree->current, tree->top)) > 0)		gnt_tree_scroll(tree, -dist);	else		redraw_tree(tree);	tree_selection_changed(tree, row, tree->current);}void _gnt_tree_init_internals(GntTree *tree, int col){	tree->ncol = col;	tree->hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_tree_row);	tree->columns = g_new0(struct _GntTreeColInfo, col);	while (col--)	{		tree->columns[col].width = 15;	}	tree->list = NULL;	tree->show_title = FALSE;}GntWidget *gnt_tree_new_with_columns(int col){	GntWidget *widget = g_object_new(GNT_TYPE_TREE, NULL);	GntTree *tree = GNT_TREE(widget);	_gnt_tree_init_internals(tree, col);		GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_SHADOW);	gnt_widget_set_take_focus(widget, TRUE);	return widget;}GntTreeRow *gnt_tree_create_row_from_list(GntTree *tree, GList *list){	GList *iter;	int i;	GntTreeRow *row = g_new0(GntTreeRow, 1);	for (i = 0, iter = list; i < tree->ncol && iter; iter = iter->next, i++)	{		GntTreeCol *col = g_new0(GntTreeCol, 1);		col->span = 1;		col->text = g_strdup(iter->data ? iter->data : "");		row->columns = g_list_append(row->columns, col);	}	return row;}GntTreeRow *gnt_tree_create_row(GntTree *tree, ...){	int i;	va_list args;	GList *list = NULL;	GntTreeRow *row;	va_start(args, tree);	for (i = 0; i < tree->ncol; i++)	{		list = g_list_append(list, va_arg(args, char *));	}	va_end(args);	row = gnt_tree_create_row_from_list(tree, list);	g_list_free(list);	return row;}void gnt_tree_set_col_width(GntTree *tree, int col, int width){	g_return_if_fail(col < tree->ncol);	tree->columns[col].width = width;}void gnt_tree_set_column_titles(GntTree *tree, ...){	int i;	va_list args;	va_start(args, tree);	for (i = 0; i < tree->ncol; i++)	{		const char *title = va_arg(args, const char *);		tree->columns[i].title = g_strdup(title);	}	va_end(args);}void gnt_tree_set_show_title(GntTree *tree, gboolean set){	tree->show_title = set;	GNT_WIDGET(tree)->priv.minh = (set ? 6 : 4);}void gnt_tree_set_compare_func(GntTree *tree, GCompareFunc func){	tree->compare = func;}void gnt_tree_set_expanded(GntTree *tree, void *key, gboolean expanded){	GntTreeRow *row = g_hash_table_lookup(tree->hash, key);	if (row) {		row->collapsed = !expanded;		if (GNT_WIDGET(tree)->window)			gnt_widget_draw(GNT_WIDGET(tree));		g_signal_emit(tree, signals[SIG_COLLAPSED], 0, key, row->collapsed);	}}void gnt_tree_set_show_separator(GntTree *tree, gboolean set){	tree->show_separator = set;}void gnt_tree_adjust_columns(GntTree *tree){	GntTreeRow *row = tree->root;	int *widths, i, twidth;	widths = g_new0(int, tree->ncol);	while (row) {		GList *iter;		for (i = 0, iter = row->columns; iter; iter = iter->next, i++) {			GntTreeCol *col = iter->data;			int w = gnt_util_onscreen_width(col->text, NULL);			if (i == 0 && row->choice)				w += 4;			if (i == 0) {				w += find_depth(row) * TAB_SIZE;			}			if (widths[i] < w)				widths[i] = w;		}		row = get_next(row);	}	twidth = 1 + 2 * (!GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_NO_BORDER));	for (i = 0; i < tree->ncol; i++) {		gnt_tree_set_col_width(tree, i, widths[i]);		if (!tree->columns[i].invisible)			twidth += widths[i] + (tree->show_separator ? 1 : 0) + 1;	}	g_free(widths);	gnt_widget_set_size(GNT_WIDGET(tree), twidth, -1);}void gnt_tree_set_hash_fns(GntTree *tree, gpointer hash, gpointer eq, gpointer kd){	g_hash_table_foreach_remove(tree->hash, return_true, NULL);	g_hash_table_destroy(tree->hash);	tree->hash = g_hash_table_new_full(hash, eq, kd, free_tree_row);}void gnt_tree_set_column_visible(GntTree *tree, int col, gboolean vis){	g_return_if_fail(col < tree->ncol);	tree->columns[col].invisible = !vis;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -