@eht16 I've just tested the PR briefly but I didn't like that parents not containing any children were still displayed - when filtering for something in the last group, one would have to scroll the tree to see it for the empty groups above.

I think it's hard/impossible to achieve that with the filter function but I tried adding an extra column to the store indicating visibility and then using gtk_tree_model_filter_set_visible_column() and it seems to work. I also added expand_all() to the result because the collapsed entries weren't very nice.

The patch is below (created very quickly by reusing code from kb_update() for the update function, possibly needs improving).

What do you think?

diff --git a/src/prefs.c b/src/prefs.c
index 57e95837e..7b8129089 100644
--- a/src/prefs.c
+++ b/src/prefs.c
@@ -87,7 +87,6 @@ static gboolean kb_find_duplicate(GtkTreeStore *store, GtkWidget *parent, GtkTre
 static void kb_filter_entry_changed_cb(GtkEntry *entry, gpointer user_data);
 static void kb_filter_entry_icon_release_cb(GtkEntry *entry, GtkEntryIconPosition icon_pos,
 		GdkEvent *event, gpointer user_data);
-static gboolean kb_tree_filter_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data);
 static gboolean kb_tree_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data);
 static void on_toolbar_show_toggled(GtkToggleButton *togglebutton, gpointer user_data);
 static void on_show_notebook_tabs_toggled(GtkToggleButton *togglebutton, gpointer user_data);
@@ -146,6 +145,7 @@ enum
 	KB_TREE_INDEX,
 	KB_TREE_EDITABLE,
 	KB_TREE_WEIGHT,
+	KB_TREE_VISIBLE,
 	KB_TREE_COLUMNS
 };
 
@@ -276,10 +276,9 @@ static void kb_init_tree(KbData *kbdata, GtkWidget *kb_filter_entry)
 	kbdata->tree = GTK_TREE_VIEW(ui_lookup_widget(ui_widgets.prefs_dialog, "treeview7"));
 
 	kbdata->store = gtk_tree_store_new(KB_TREE_COLUMNS,
-		G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_BOOLEAN, G_TYPE_INT);
+		G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_BOOLEAN, G_TYPE_INT, G_TYPE_BOOLEAN);
 	filter_model = gtk_tree_model_filter_new(GTK_TREE_MODEL(kbdata->store), NULL);
-	gtk_tree_model_filter_set_visible_func(
-		GTK_TREE_MODEL_FILTER(filter_model), kb_tree_filter_func, kb_filter_entry, NULL);
+	gtk_tree_model_filter_set_visible_column(GTK_TREE_MODEL_FILTER(filter_model), KB_TREE_VISIBLE);
 	/* set model to tree view */
 	gtk_tree_view_set_model(GTK_TREE_VIEW(kbdata->tree), filter_model);
 	g_object_unref(filter_model);
@@ -376,14 +375,14 @@ static void kb_init(KbData *kbdata, GtkWidget *kb_filter_entry)
 	{
 		gtk_tree_store_append(kbdata->store, &parent, NULL);
 		gtk_tree_store_set(kbdata->store, &parent, KB_TREE_ACTION, group->label,
-			KB_TREE_INDEX, g, -1);
+			KB_TREE_INDEX, g, KB_TREE_VISIBLE, TRUE, -1);
 
 		foreach_ptr_array(kb, i, group->key_items)
 		{
 			label = keybindings_get_label(kb);
 			gtk_tree_store_append(kbdata->store, &iter, &parent);
 			gtk_tree_store_set(kbdata->store, &iter, KB_TREE_ACTION, label,
-				KB_TREE_EDITABLE, TRUE, KB_TREE_INDEX, kb->id, -1);
+				KB_TREE_EDITABLE, TRUE, KB_TREE_INDEX, kb->id, KB_TREE_VISIBLE, TRUE, -1);
 			kb_set_shortcut(kbdata->store, &iter, kb->key, kb->mods);
 			g_free(label);
 		}
@@ -1413,10 +1412,62 @@ static void kb_cell_edited_cb(GtkCellRendererText *cellrenderertext,
 }
 
 
+static void update_visibility(GtkTreeStore *store, const gchar *entry_text)
+{
+	GtkTreeModel *model = GTK_TREE_MODEL(store);
+	GtkTreeIter child, parent;
+
+	/* get first parent */
+	if (! gtk_tree_model_iter_children(model, &parent, NULL))
+		return;
+
+	/* foreach parent */
+	while (TRUE)
+	{
+		gboolean visible_children = FALSE;
+
+		/* get first child */
+		if (! gtk_tree_model_iter_children(model, &child, &parent))
+			return;
+
+		/* foreach child */
+		while (TRUE)
+		{
+			gboolean visible;
+			gchar *action_name;
+
+			gtk_tree_model_get(model, &child, KB_TREE_ACTION, &action_name, -1);
+			if (!action_name || EMPTY(entry_text))
+				visible = TRUE;
+			else
+				visible = utils_utf8_substring_match(entry_text, action_name);
+			g_free(action_name);
+
+			if (visible)
+				visible_children = TRUE;
+
+			gtk_tree_store_set(store, &child, KB_TREE_VISIBLE, visible, -1);
+
+			if (! gtk_tree_model_iter_next(model, &child))
+				break;
+		}
+
+		gtk_tree_store_set(store, &parent, KB_TREE_VISIBLE, visible_children, -1);
+
+		if (! gtk_tree_model_iter_next(model, &parent))
+			return;
+	}
+}
+
+
 static void kb_filter_entry_changed_cb(GtkEntry *entry, gpointer user_data)
 {
 	GtkTreeModel *filter_model = gtk_tree_view_get_model(GTK_TREE_VIEW(global_kb_data.tree));
+	const gchar *entry_text = gtk_entry_get_text(entry);
+
+	update_visibility(global_kb_data.store, entry_text);
 	gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(filter_model));
+	gtk_tree_view_expand_all(global_kb_data.tree);
 }
 
 
@@ -1428,31 +1479,6 @@ static void kb_filter_entry_icon_release_cb(GtkEntry *entry, GtkEntryIconPositio
 }
 
 
-static gboolean kb_tree_filter_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
-{
-	const gchar *key;
-	gboolean matched;
-	gchar *action_name;
-	GtkWidget *kb_filter_entry = user_data;
-
-	// always show categories
-	if (gtk_tree_model_iter_has_child(model, iter))
-		return TRUE;
-
-	gtk_tree_model_get(model, iter, KB_TREE_ACTION, &action_name, -1);
-	if (!action_name)
-		return TRUE;
-
-	key = gtk_entry_get_text(GTK_ENTRY(kb_filter_entry));
-	if (EMPTY(key))
-		return TRUE;
-
-	matched = utils_utf8_substring_match(key, action_name);
-	g_free(action_name);
-	return matched;
-}
-
-
 static gboolean kb_tree_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
 {
 	if (event->keyval == GDK_KEY_f && (event->state & GEANY_PRIMARY_MOD_MASK))


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <geany/geany/pull/4192/c2574098572@github.com>