# HG changeset patch # User Sadrul Habib Chowdhury # Date 1184379342 0 # Node ID ffa46a399f3ccaf2489509157972f20107f0843b # Parent 79e27f0c6f05e2e9f24186b23a446bb930f1fc1f Allow setting the search column in a tree to use for typeahead searching. Hide some of the internals if GntTree. diff -r 79e27f0c6f05 -r ffa46a399f3c finch/libgnt/gnttree.c --- a/finch/libgnt/gnttree.c Sat Jul 14 01:28:24 2007 +0000 +++ b/finch/libgnt/gnttree.c Sat Jul 14 02:15:42 2007 +0000 @@ -29,7 +29,7 @@ #include #define SEARCH_TIMEOUT 4000 /* 4 secs */ -#define SEARCHING(tree) (tree->search && tree->search->len > 0) +#define SEARCHING(tree) (tree->priv->search && tree->priv->search->len > 0) #define COLUMN_INVISIBLE(tree, index) (tree->columns[index].flags & GNT_TREE_COLUMN_INVISIBLE) #define BINARY_DATA(tree, index) (tree->columns[index].flags & GNT_TREE_COLUMN_BINARY_DATA) @@ -50,6 +50,16 @@ SIGS, }; +struct _GntTreePriv +{ + GString *search; + int search_timeout; + int search_column; + + GCompareFunc compare; + int lastvisible; +}; + #define TAB_SIZE 3 /* XXX: Make this one into a GObject? @@ -147,11 +157,10 @@ row_matches_search(GntTreeRow *row) { GntTree *t = row->tree; - if (t->search && t->search->len > 0) { - /* XXX: Allow setting the search column. And make sure the search column - * doesn't contain binary data. */ - char *one = g_utf8_casefold(((GntTreeCol*)row->columns->data)->text, -1); - char *two = g_utf8_casefold(t->search->str, -1); + if (t->priv->search && t->priv->search->len > 0) { + GntTreeCol *col = (col = g_list_nth_data(row->columns, t->priv->search_column)) ? col : row->columns->data; + char *one = g_utf8_casefold(col->text, -1); + char *two = g_utf8_casefold(t->priv->search->str, -1); char *z = strstr(one, two); g_free(one); g_free(two); @@ -576,11 +585,11 @@ (row ? ACS_DARROW : ' ') | COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D)); /* If there's a search-text, show it in the bottom of the tree */ - if (tree->search && tree->search->len > 0) { - const char *str = gnt_util_onscreen_width_to_pointer(tree->search->str, scrcol - 1, NULL); + if (tree->priv->search && tree->priv->search->len > 0) { + const char *str = gnt_util_onscreen_width_to_pointer(tree->priv->search->str, scrcol - 1, NULL); wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D)); mvwaddnstr(widget->window, widget->priv.height - pos - 1, pos, - tree->search->str, str - tree->search->str); + tree->priv->search->str, str - tree->priv->search->str); } gnt_widget_queue_update(widget); @@ -609,7 +618,7 @@ for (i = 0; i < tree->ncol; i++) if (!COLUMN_INVISIBLE(tree, i)) { width = width + tree->columns[i].width; - if (tree->lastvisible != i) + if (tree->priv->lastvisible != i) width++; } widget->priv.width = width; @@ -750,11 +759,11 @@ static void end_search(GntTree *tree) { - if (tree->search) { - g_source_remove(tree->search_timeout); - g_string_free(tree->search, TRUE); - tree->search = NULL; - tree->search_timeout = 0; + if (tree->priv->search) { + g_source_remove(tree->priv->search_timeout); + g_string_free(tree->priv->search, TRUE); + tree->priv->search = NULL; + tree->priv->search_timeout = 0; } } @@ -778,19 +787,19 @@ if (text[0] == '\r') { end_search(tree); gnt_widget_activate(widget); - } else if (tree->search) { + } else if (tree->priv->search) { gboolean changed = TRUE; if (isalnum(*text)) { - tree->search = g_string_append_c(tree->search, *text); + tree->priv->search = g_string_append_c(tree->priv->search, *text); } else if (g_utf8_collate(text, GNT_KEY_BACKSPACE) == 0) { - if (tree->search->len) - tree->search->str[--tree->search->len] = '\0'; + if (tree->priv->search->len) + tree->priv->search->str[--tree->priv->search->len] = '\0'; } else changed = FALSE; if (changed) { redraw_tree(tree); - g_source_remove(tree->search_timeout); - tree->search_timeout = g_timeout_add(SEARCH_TIMEOUT, search_timeout, tree); + g_source_remove(tree->priv->search_timeout); + tree->priv->search_timeout = g_timeout_add(SEARCH_TIMEOUT, search_timeout, tree); } return TRUE; } else if (text[0] == ' ' && text[1] == 0) { @@ -821,21 +830,26 @@ } static void +gnt_tree_free_columns(GntTree *tree) +{ + int i; + for (i = 0; i < tree->ncol; i++) { + g_free(tree->columns[i].title); + } + g_free(tree->columns); +} + +static void gnt_tree_destroy(GntWidget *widget) { GntTree *tree = GNT_TREE(widget); - int i; end_search(tree); if (tree->hash) g_hash_table_destroy(tree->hash); g_list_free(tree->list); - - for (i = 0; i < tree->ncol; i++) - { - g_free(tree->columns[i].title); - } - g_free(tree->columns); + gnt_tree_free_columns(tree); + g_free(tree->priv); } static gboolean @@ -894,10 +908,10 @@ start_search(GntBindable *bindable, GList *list) { GntTree *tree = GNT_TREE(bindable); - if (tree->search) + if (tree->priv->search) return FALSE; - tree->search = g_string_new(NULL); - tree->search_timeout = g_timeout_add(SEARCH_TIMEOUT, search_timeout, tree); + tree->priv->search = g_string_new(NULL); + tree->priv->search_timeout = g_timeout_add(SEARCH_TIMEOUT, search_timeout, tree); return TRUE; } @@ -905,7 +919,7 @@ end_search_action(GntBindable *bindable, GList *list) { GntTree *tree = GNT_TREE(bindable); - if (tree->search == NULL) + if (tree->priv->search == NULL) return FALSE; end_search(tree); redraw_tree(tree); @@ -1026,6 +1040,7 @@ GntWidget *widget = GNT_WIDGET(instance); GntTree *tree = GNT_TREE(widget); tree->show_separator = TRUE; + tree->priv = g_new0(GntTreePriv, 1); GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X | GNT_WIDGET_GROW_Y); widget->priv.minw = 4; widget->priv.minh = 1; @@ -1140,7 +1155,7 @@ { GntTreeRow *row; - if (tree->compare == NULL) + if (tree->priv->compare == NULL) return NULL; if (parent == NULL) @@ -1156,7 +1171,7 @@ while (row) { - if (tree->compare(key, row->key) < 0) + if (tree->priv->compare(key, row->key) < 0) return (row->prev ? row->prev->key : NULL); if (row->next) row = row->next; @@ -1171,7 +1186,7 @@ GntTreeRow *row, *q, *s; int current, newp; - if (!tree->compare) + if (!tree->priv->compare) return; row = g_hash_table_lookup(tree->hash, key); @@ -1186,7 +1201,7 @@ q = NULL; while (s) { - if (tree->compare(row->key, s->key) < 0) + if (tree->priv->compare(row->key, s->key) < 0) break; q = s; s = s->next; @@ -1242,7 +1257,7 @@ g_hash_table_replace(tree->hash, key, row); row->tree = tree; - if (bigbro == NULL && tree->compare) + if (bigbro == NULL && tree->priv->compare) { bigbro = find_position(tree, key, parent); } @@ -1473,7 +1488,7 @@ g_return_val_if_fail(!r || !r->choice, NULL); if (bigbro == NULL) { - if (tree->compare) + if (tree->priv->compare) bigbro = find_position(tree, key, parent); else { r = g_hash_table_lookup(tree->hash, parent); @@ -1551,12 +1566,12 @@ static void _gnt_tree_init_internals(GntTree *tree, int col) { - gnt_tree_destroy(GNT_WIDGET(tree)); + gnt_tree_free_columns(tree); 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); - tree->lastvisible = col - 1; + tree->priv->lastvisible = col - 1; while (col--) { tree->columns[col].width = 15; @@ -1659,7 +1674,7 @@ void gnt_tree_set_compare_func(GntTree *tree, GCompareFunc func) { - tree->compare = func; + tree->priv->compare = func; } void gnt_tree_set_expanded(GntTree *tree, void *key, gboolean expanded) @@ -1707,7 +1722,7 @@ gnt_tree_set_col_width(tree, i, widths[i]); if (!COLUMN_INVISIBLE(tree, i)) { twidth = twidth + widths[i]; - if (tree->lastvisible != i) + if (tree->priv->lastvisible != i) twidth += 1; } } @@ -1738,13 +1753,13 @@ set_column_flag(tree, col, GNT_TREE_COLUMN_INVISIBLE, !vis); if (vis) { /* the column is visible */ - if (tree->lastvisible < col) - tree->lastvisible = col; + if (tree->priv->lastvisible < col) + tree->priv->lastvisible = col; } else { - if (tree->lastvisible == col) - while (tree->lastvisible) { - tree->lastvisible--; - if (!COLUMN_INVISIBLE(tree, tree->lastvisible)) + if (tree->priv->lastvisible == col) + while (tree->priv->lastvisible) { + tree->priv->lastvisible--; + if (!COLUMN_INVISIBLE(tree, tree->priv->lastvisible)) break; } } @@ -1776,3 +1791,10 @@ } } +void gnt_tree_set_search_column(GntTree *tree, int col) +{ + g_return_if_fail(col < tree->ncol); + g_return_if_fail(!BINARY_DATA(tree, col)); + tree->priv->search_column = col; +} + diff -r 79e27f0c6f05 -r ffa46a399f3c finch/libgnt/gnttree.h --- a/finch/libgnt/gnttree.h Sat Jul 14 01:28:24 2007 +0000 +++ b/finch/libgnt/gnttree.h Sat Jul 14 02:15:42 2007 +0000 @@ -83,11 +83,7 @@ gboolean show_title; gboolean show_separator; /* Whether to show column separators */ - GString *search; - int search_timeout; - - GCompareFunc compare; - int lastvisible; + GntTreePriv *priv; }; struct _GntTreeClass @@ -504,6 +500,14 @@ */ void gnt_tree_set_column_width_ratio(GntTree *tree, int cols[]); +/** + * Set the column to use for typeahead searching. + * + * @param tree The tree + * @param col The index of the column + */ +void gnt_tree_set_search_column(GntTree *tree, int col); + G_END_DECLS #endif /* GNT_TREE_H */