Remove old search and implement new search using filtering.

This commit is contained in:
Mario Hüttel 2019-02-05 20:38:52 +01:00
parent 1d67424bc9
commit 6937d24699
2 changed files with 51 additions and 64 deletions

View File

@ -61,71 +61,55 @@ static gboolean tree_sel_func(GtkTreeSelection *selection,
} }
/** /**
* @brief tree_sel_search_func * @brief cell_store_filter_visible_func Decides whether an element of the tree model @p model is visible.
* @param model Tree model * @param model Tree model
* @param column Column id * @param iter Current element / iter in Model to check
* @param key Search key * @param data Data. Set to static stores variable
* @param iter Iterator * @return TRUE if visible, else FALSE
* @param search_data User data. In this case always NULL * @note TODO: Maybe implement Damerau-Levenshtein distance matching
* @return returns false (!) if matches
*/ */
static gboolean tree_sel_search_func(GtkTreeModel *model, gint column, const gchar *key, GtkTreeIter *iter, gpointer *search_data) static gboolean cell_store_filter_visible_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
{ {
(void)search_data; struct tree_stores *stores = (struct tree_stores *)data;
(void)column;
struct gds_cell *cell; struct gds_cell *cell;
struct gds_library *lib; struct gds_library *lib;
GtkTreePath *path; gboolean result = FALSE;
GtkTreeIter lib_iter; const char *search_string;
char *lib_str = NULL, *cell_str = NULL, *div_str = NULL, *key_copy;
gboolean result = TRUE;
gtk_tree_model_get(model, iter, CELL_SEL_CELL, &cell, -1); if (!model || !iter || !stores)
path = gtk_tree_model_get_path(model, iter); goto exit_filter;
gtk_tree_model_get(model, iter, CELL_SEL_CELL, &cell, CELL_SEL_LIBRARY, &lib, -1);
if (lib) {
result = TRUE;
goto exit_filter;
}
/* Libraries not selectable */
if (!cell) if (!cell)
return TRUE; goto exit_filter;
if (!gtk_tree_path_up(path)) { search_string = gtk_entry_get_text(stores->search_entry);
gtk_tree_path_free(path);
printf("Cell without parent library found during search! Somethings really wrong!!!\n");
return TRUE;
}
/* Find name of parent library */ /* Show all, if field is empty */
gtk_tree_model_get_iter(model, &lib_iter, path); if (!strlen(search_string))
gtk_tree_model_get(model, &lib_iter, CELL_SEL_LIBRARY, &lib, -1); result = TRUE;
gtk_tree_path_free(path);
if (!lib) { if (strstr(cell->name, search_string))
printf("Parent library invalid!\n"); result = TRUE;
return TRUE;
}
/* Search for Library/Cell division operator */ gtk_tree_view_expand_all(stores->base_tree_view);
key_copy = strdup(key);
if (!key_copy)
goto abort_search;
if ((div_str = strstr(key_copy, ":"))) { exit_filter:
lib_str = key_copy;
*div_str = 0x00;
cell_str = div_str + 1;
if (!strncmp(lib_str, lib->name, sizeof(lib->name))) {
if (!strncmp(cell_str, cell->name, sizeof(cell->name)))
result = FALSE;
}
} else {
result = (strncmp(key, cell->name, sizeof(cell->name)) ? TRUE : FALSE);
}
abort_search:
return result; return result;
} }
static void change_filter(GtkWidget *entry, gpointer data)
{
struct tree_stores *stores = (struct tree_stores *)data;
gtk_tree_model_filter_refilter(stores->filter);
}
/** /**
* @brief Setup a GtkTreeView with the necessary columns * @brief Setup a GtkTreeView with the necessary columns
* @param view Tree view to set up * @param view Tree view to set up
@ -135,16 +119,26 @@ abort_search:
struct tree_stores *setup_cell_selector(GtkTreeView* view, GtkEntry *search_entry) struct tree_stores *setup_cell_selector(GtkTreeView* view, GtkEntry *search_entry)
{ {
static struct tree_stores stores; static struct tree_stores stores;
GtkTreeStore *cell_store;
GtkCellRenderer *render_dates; GtkCellRenderer *render_dates;
GtkCellRenderer *render_cell; GtkCellRenderer *render_cell;
GtkCellRenderer *render_lib; GtkCellRenderer *render_lib;
GtkTreeViewColumn *column; GtkTreeViewColumn *column;
cell_store = gtk_tree_store_new(CELL_SEL_COLUMN_COUNT, G_TYPE_POINTER, G_TYPE_POINTER, GDK_TYPE_RGBA, G_TYPE_STRING, G_TYPE_STRING); stores.base_tree_view = view;
gtk_tree_view_set_model(view, GTK_TREE_MODEL(cell_store)); stores.search_entry = search_entry;
stores.base_store = gtk_tree_store_new(CELL_SEL_COLUMN_COUNT, G_TYPE_POINTER, G_TYPE_POINTER, GDK_TYPE_RGBA, G_TYPE_STRING, G_TYPE_STRING);
/* Searching */
if (search_entry) {
stores.filter = GTK_TREE_MODEL_FILTER(gtk_tree_model_filter_new(GTK_TREE_MODEL(stores.base_store), NULL));
gtk_tree_model_filter_set_visible_func (stores.filter,
(GtkTreeModelFilterVisibleFunc)cell_store_filter_visible_func,
&stores, NULL);
g_signal_connect(GTK_SEARCH_ENTRY(search_entry), "search-changed", G_CALLBACK(change_filter), &stores);
}
gtk_tree_view_set_model(view, GTK_TREE_MODEL(stores.filter));
render_dates = gtk_cell_renderer_text_new(); render_dates = gtk_cell_renderer_text_new();
render_cell = lib_cell_renderer_new(); render_cell = lib_cell_renderer_new();
@ -167,16 +161,6 @@ struct tree_stores *setup_cell_selector(GtkTreeView* view, GtkEntry *search_entr
* This prevents selecting a library */ * This prevents selecting a library */
gtk_tree_selection_set_select_function(gtk_tree_view_get_selection(view), tree_sel_func, NULL, NULL); gtk_tree_selection_set_select_function(gtk_tree_view_get_selection(view), tree_sel_func, NULL, NULL);
/* Searching */
if (search_entry) {
gtk_tree_view_set_enable_search(view, TRUE);
gtk_tree_view_set_search_column(view, CELL_SEL_CELL);
gtk_tree_view_set_search_equal_func(view, (GtkTreeViewSearchEqualFunc)tree_sel_search_func, NULL, NULL);
gtk_tree_view_set_search_entry(view, search_entry);
}
stores.base_store = cell_store;
return &stores; return &stores;
} }
/** @} */ /** @} */

View File

@ -44,7 +44,10 @@ enum cell_store_columns {
}; };
struct tree_stores { struct tree_stores {
GtkTreeView *base_tree_view;
GtkTreeStore *base_store; GtkTreeStore *base_store;
GtkTreeModelFilter *filter;
GtkEntry *search_entry;
}; };
struct tree_stores *setup_cell_selector(GtkTreeView* view, GtkEntry *search_entry); struct tree_stores *setup_cell_selector(GtkTreeView* view, GtkEntry *search_entry);