[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250624150645.1107002-45-masahiroy@kernel.org>
Date: Wed, 25 Jun 2025 00:05:32 +0900
From: Masahiro Yamada <masahiroy@...nel.org>
To: linux-kbuild@...r.kernel.org
Cc: Masahiro Yamada <masahiroy@...nel.org>,
linux-kernel@...r.kernel.org
Subject: [PATCH 44/66] kconfig: gconf: use GtkTreeModelFilter to control row visibility
Currently, update_tree() adds/removes entries to show/hide rows.
This approach is extremely complicated.
Use the tree model filter to control row visibility instead.
Do not toggle the MENU_CHANGED flag, as it is hard to control
this correctly.
Signed-off-by: Masahiro Yamada <masahiroy@...nel.org>
---
scripts/kconfig/gconf.c | 217 +++++++++++++++-------------------------
1 file changed, 80 insertions(+), 137 deletions(-)
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
index 184678dd4fa6..a0cc7cb98670 100644
--- a/scripts/kconfig/gconf.c
+++ b/scripts/kconfig/gconf.c
@@ -59,7 +59,9 @@ enum {
static void display_list(void);
static void display_tree(GtkTreeStore *store, struct menu *menu);
static void display_tree_part(void);
-static void update_tree(struct menu *src, GtkTreeIter * dst);
+static gchar **fill_row(struct menu *menu);
+static void set_node(GtkTreeStore *tree, GtkTreeIter *node,
+ struct menu *menu, gchar **row);
static void conf_changed(bool dirty)
{
@@ -110,6 +112,47 @@ static void select_menu(GtkTreeView *view, struct menu *match)
_select_menu(view, gtk_tree_view_get_model(view), NULL, match);
}
+static void _update_row_visibility(GtkTreeView *view)
+{
+ GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER(gtk_tree_view_get_model(view));
+
+ gtk_tree_model_filter_refilter(filter);
+}
+
+static void update_row_visibility(void)
+{
+ if (view_mode == SPLIT_VIEW)
+ _update_row_visibility(GTK_TREE_VIEW(tree1_w));
+ _update_row_visibility(GTK_TREE_VIEW(tree2_w));
+}
+
+static void _update_tree(GtkTreeStore *store, GtkTreeIter *parent)
+{
+ GtkTreeModel *model = GTK_TREE_MODEL(store);
+ GtkTreeIter iter;
+ gboolean valid;
+
+ valid = gtk_tree_model_iter_children(model, &iter, parent);
+ while (valid) {
+ struct menu *menu;
+
+ gtk_tree_model_get(model, &iter, COL_MENU, &menu, -1);
+
+ if (menu)
+ set_node(store, &iter, menu, fill_row(menu));
+
+ _update_tree(store, &iter);
+
+ valid = gtk_tree_model_iter_next(model, &iter);
+ }
+}
+
+static void update_tree(GtkTreeStore *store)
+{
+ _update_tree(store, NULL);
+ update_row_visibility();
+}
+
static void set_view_mode(enum view_mode mode)
{
view_mode = mode;
@@ -328,24 +371,21 @@ static void on_set_option_mode1_activate(GtkMenuItem *menuitem,
gpointer user_data)
{
opt_mode = OPT_NORMAL;
- gtk_tree_store_clear(tree2);
- display_tree(tree2, &rootmenu); /* instead of update_tree to speed-up */
+ update_row_visibility();
}
static void on_set_option_mode2_activate(GtkMenuItem *menuitem,
gpointer user_data)
{
opt_mode = OPT_ALL;
- gtk_tree_store_clear(tree2);
- display_tree(tree2, &rootmenu); /* instead of update_tree to speed-up */
+ update_row_visibility();
}
static void on_set_option_mode3_activate(GtkMenuItem *menuitem,
gpointer user_data)
{
opt_mode = OPT_PROMPT;
- gtk_tree_store_clear(tree2);
- display_tree(tree2, &rootmenu); /* instead of update_tree to speed-up */
+ update_row_visibility();
}
static void on_introduction1_activate(GtkMenuItem *menuitem, gpointer user_data)
@@ -559,7 +599,7 @@ static void renderer_edited(GtkCellRendererText * cell,
sym_set_string_value(sym, new_def);
- update_tree(&rootmenu, NULL);
+ update_tree(tree2);
free:
gtk_tree_path_free(path);
@@ -590,9 +630,9 @@ static void change_sym_value(struct menu *menu, gint col)
newval = yes;
sym_set_tristate_value(sym, newval);
if (view_mode == FULL_VIEW)
- update_tree(&rootmenu, NULL);
+ update_tree(tree2);
else if (view_mode == SPLIT_VIEW) {
- update_tree(browsed, NULL);
+ update_tree(tree2);
display_list();
}
else if (view_mode == SINGLE_VIEW)
@@ -613,9 +653,9 @@ static void toggle_sym_value(struct menu *menu)
sym_toggle_tristate_value(menu->sym);
if (view_mode == FULL_VIEW)
- update_tree(&rootmenu, NULL);
+ update_tree(tree2);
else if (view_mode == SPLIT_VIEW) {
- update_tree(browsed, NULL);
+ update_tree(tree2);
display_list();
}
else if (view_mode == SINGLE_VIEW)
@@ -842,7 +882,6 @@ static gchar **fill_row(struct menu *menu)
row[COL_NAME] = g_strdup(sym->name);
sym_calc_value(sym);
- menu->flags &= ~MENU_CHANGED;
if (sym_is_choice(sym)) { // parse childs for getting final value
struct menu *child;
@@ -947,120 +986,6 @@ static void set_node(GtkTreeStore *tree, GtkTreeIter *node,
g_object_unref(pix);
}
-/* Find a node in the GTK+ tree */
-static GtkTreeIter found;
-
-/*
- * Find a menu in the GtkTree starting at parent.
- */
-static GtkTreeIter *gtktree_iter_find_node(GtkTreeIter *parent,
- struct menu *tofind)
-{
- GtkTreeIter iter;
- GtkTreeIter *child = &iter;
- gboolean valid;
- GtkTreeIter *ret;
-
- valid = gtk_tree_model_iter_children(model2, child, parent);
- while (valid) {
- struct menu *menu;
-
- gtk_tree_model_get(model2, child, 6, &menu, -1);
-
- if (menu == tofind) {
- memcpy(&found, child, sizeof(GtkTreeIter));
- return &found;
- }
-
- ret = gtktree_iter_find_node(child, tofind);
- if (ret)
- return ret;
-
- valid = gtk_tree_model_iter_next(model2, child);
- }
-
- return NULL;
-}
-
-
-/*
- * Update the tree by adding/removing entries
- * Does not change other nodes
- */
-static void update_tree(struct menu *src, GtkTreeIter * dst)
-{
- struct menu *child1;
- GtkTreeIter iter, tmp;
- GtkTreeIter *child2 = &iter;
- gboolean valid;
- GtkTreeIter *sibling;
- struct symbol *sym;
- struct menu *menu1, *menu2;
-
- valid = gtk_tree_model_iter_children(model2, child2, dst);
- for (child1 = src->list; child1; child1 = child1->next) {
-
- sym = child1->sym;
-
- reparse:
- menu1 = child1;
- if (valid)
- gtk_tree_model_get(model2, child2, COL_MENU,
- &menu2, -1);
- else
- menu2 = NULL; // force adding of a first child
-
- if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) ||
- (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) ||
- (opt_mode == OPT_ALL && !menu_get_prompt(child1))) {
-
- /* remove node */
- if (gtktree_iter_find_node(dst, menu1) != NULL) {
- memcpy(&tmp, child2, sizeof(GtkTreeIter));
- valid = gtk_tree_model_iter_next(model2,
- child2);
- gtk_tree_store_remove(tree2, &tmp);
- if (!valid)
- return; /* next parent */
- else
- goto reparse; /* next child */
- } else
- continue;
- }
-
- if (menu1 != menu2) {
- if (gtktree_iter_find_node(dst, menu1) == NULL) { // add node
- if (!valid && !menu2)
- sibling = NULL;
- else
- sibling = child2;
- gtk_tree_store_insert_before(tree2,
- child2,
- dst, sibling);
- set_node(tree2, child2, menu1, fill_row(menu1));
- if (menu2 == NULL)
- valid = TRUE;
- } else { // remove node
- memcpy(&tmp, child2, sizeof(GtkTreeIter));
- valid = gtk_tree_model_iter_next(model2,
- child2);
- gtk_tree_store_remove(tree2, &tmp);
- if (!valid)
- return; // next parent
- else
- goto reparse; // next child
- }
- } else if (sym && (child1->flags & MENU_CHANGED)) {
- set_node(tree2, child2, menu1, fill_row(menu1));
- }
-
- update_tree(child1, child2);
-
- valid = gtk_tree_model_iter_next(model2, child2);
- }
-}
-
-
/* Display the whole tree (single/split/full view) */
static void _display_tree(GtkTreeStore *tree, struct menu *menu,
GtkTreeIter *parent)
@@ -1083,8 +1008,6 @@ static void _display_tree(GtkTreeStore *tree, struct menu *menu,
prop = child->prompt;
ptype = prop ? prop->type : P_UNKNOWN;
- menu->flags &= ~MENU_CHANGED;
-
if ((view_mode == SPLIT_VIEW)
&& !(child->flags & MENU_ROOT) && (tree == tree1))
continue;
@@ -1093,12 +1016,8 @@ static void _display_tree(GtkTreeStore *tree, struct menu *menu,
&& (tree == tree2))
continue;
- if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) ||
- (opt_mode == OPT_PROMPT && menu_has_prompt(child)) ||
- (opt_mode == OPT_ALL && menu_get_prompt(child))) {
- gtk_tree_store_append(tree, &iter, parent);
- set_node(tree, &iter, child, fill_row(child));
- }
+ gtk_tree_store_append(tree, &iter, parent);
+ set_node(tree, &iter, child, fill_row(child));
if ((view_mode != FULL_VIEW) && (ptype == P_MENU)
&& (tree == tree2))
@@ -1313,6 +1232,20 @@ static void init_main_window(const gchar *glade_file)
gtk_widget_show(main_wnd);
}
+static gboolean visible_func(GtkTreeModel *model, GtkTreeIter *iter,
+ gpointer data)
+{
+ struct menu *menu;
+
+ gtk_tree_model_get(model, iter, COL_MENU, &menu, -1);
+
+ if (!menu)
+ return FALSE;
+
+ return menu_is_visible(menu) || opt_mode == OPT_ALL ||
+ (opt_mode == OPT_PROMPT && menu_has_prompt(menu));
+}
+
static void init_tree_model(void)
{
tree2 = gtk_tree_store_new(COL_NUMBER,
@@ -1344,8 +1277,13 @@ static void init_left_tree(void)
GtkCellRenderer *renderer;
GtkTreeSelection *sel;
GtkTreeViewColumn *column;
+ GtkTreeModel *filter;
- gtk_tree_view_set_model(view, model1);
+ filter = gtk_tree_model_filter_new(model1, NULL);
+
+ gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filter),
+ visible_func, NULL, NULL);
+ gtk_tree_view_set_model(view, filter);
column = gtk_tree_view_column_new();
gtk_tree_view_append_column(view, column);
@@ -1379,9 +1317,14 @@ static void init_right_tree(void)
GtkCellRenderer *renderer;
GtkTreeSelection *sel;
GtkTreeViewColumn *column;
+ GtkTreeModel *filter;
gint i;
- gtk_tree_view_set_model(view, model2);
+ filter = gtk_tree_model_filter_new(model2, NULL);
+
+ gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filter),
+ visible_func, NULL, NULL);
+ gtk_tree_view_set_model(view, filter);
column = gtk_tree_view_column_new();
gtk_tree_view_append_column(view, column);
--
2.43.0
Powered by blists - more mailing lists