diff --git a/demos/gtk-demo/geninclude.py b/demos/gtk-demo/geninclude.py index bae6e57f47..2ebfaeb625 100755 --- a/demos/gtk-demo/geninclude.py +++ b/demos/gtk-demo/geninclude.py @@ -6,6 +6,22 @@ import re import os from collections import * +def add_quotes(s): + return "\"" + s.lower() + "\"" + +def wordify(s): + return s.strip().rstrip(".,;:") + +def is_keyword(s): + if s == "GTK": + return False + elif s.startswith(("Gtk", "Gdk", "Pango")): + return True + elif s.startswith("G") and s[1].isupper(): + return True + else: + return False + out_file = sys.argv[1] in_files = sys.argv[2:] @@ -19,13 +35,14 @@ struct _DemoData { const char *name; const char *title; + const char **keywords; const char *filename; GDoDemoFunc func; DemoData *children; }; """ -# Demo = namedtuple('Demo', ['name', 'title', 'file', 'func']) +# Demo = namedtuple('Demo', ['name', 'title', 'keywords', 'file', 'func']) demos = [] @@ -34,14 +51,17 @@ for demo_file in in_files: demo_name = filename.replace(".c", "") with open(demo_file, 'r', encoding='utf-8') as f: title = f.readline().replace("/*", "").strip() - + keywords = set() + line = f.readline().strip(); + while not line.endswith('*/'): + if line.startswith("* #Keywords:"): + keywords = keywords.union(set(map(wordify, line.replace ("* #Keywords:", "").strip().split(",")))) + else: + keywords = keywords.union(set(filter(is_keyword, map(wordify, line.replace ("* ", "").split())))) + line = f.readline().strip() file_output += "GtkWidget *do_" + demo_name + " (GtkWidget *do_widget);\n" - # demos += Demo(name = demo_name, - # title = title, - # file = demo_file, - # func = "do_" + title) - demos.append((demo_name, title, filename, "do_" + demo_name, -1)) + demos.append((demo_name, title, keywords, filename, "do_" + demo_name, -1)) # Generate a List of "Parent names" parents = [] @@ -57,7 +77,7 @@ for demo in demos: if not parent_name in parents: parents.append(parent_name) parent_ids.append(parent_index) - demos.append(("NULL", parent_name, "NULL", "NULL", parent_index)) + demos.append(("NULL", parent_name, set(), "NULL", "NULL", parent_index)) parent_index = parent_index + 1 @@ -71,8 +91,7 @@ for parent in parents: for child in demos: if child[1].startswith(parent + "/"): title = child[1][child[1].rfind('/') + 1:] - file_output += " { \"" + child[0] + "\", \"" + title + "\", \"" + child[2] + "\", " + child[3] + ", NULL },\n" - + file_output += " { \"" + child[0] + "\", \"" + title + "\", " + "(const char*[]) {" + ", ".join(list(map(add_quotes, child[2])) + ["NULL"]) + " }, \"" + child[3] + "\", " + child[4] + ", NULL },\n" file_output += " { NULL }\n};\n" i = i + 1 @@ -86,9 +105,10 @@ for demo in demos: # Do not generate one of these for demos with a parent demo if "/" not in demo[1]: child_array = "NULL" - name = demo[0]; - title = demo[1]; - file = demo[2] + name = demo[0] + title = demo[1] + keywords = demo[2] + file = demo[3] if name != "NULL": name = "\"" + name + "\"" if title != "NULL": @@ -96,9 +116,9 @@ for demo in demos: if file != "NULL": file = "\"" + file + "\"" - if demo[4] != -1: - child_array = "child" + str(demo[4]) - file_output += " { " + name + ", " + title + ", " + file + ", " + demo[3] + ", " + child_array + " },\n" + if demo[5] != -1: + child_array = "child" + str(demo[5]) + file_output += " { " + name + ", " + title + ", " + "(const char*[]) {" + ", ".join(list(map(add_quotes, keywords)) + ["NULL"]) + " }, " + file + ", " + demo[4] + ", " + child_array + " },\n" file_output += " { NULL }\n};\n" diff --git a/demos/gtk-demo/main.c b/demos/gtk-demo/main.c index 3011c3e890..40789d773e 100644 --- a/demos/gtk-demo/main.c +++ b/demos/gtk-demo/main.c @@ -28,6 +28,7 @@ struct _GtkDemo const char *name; const char *title; + const char **keywords; const char *filename; GDoDemoFunc func; GListModel *children_model; @@ -38,6 +39,7 @@ enum { PROP_FILENAME, PROP_NAME, PROP_TITLE, + PROP_KEYWORDS, N_PROPS }; @@ -70,6 +72,10 @@ gtk_demo_get_property (GObject *object, g_value_set_string (value, self->title); break; + case PROP_KEYWORDS: + g_value_set_boxed (value, self->keywords); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -100,6 +106,12 @@ static void gtk_demo_class_init (GtkDemoClass *klass) "title", NULL, G_PARAM_READABLE); + properties[PROP_KEYWORDS] = + g_param_spec_string ("keywords", + "keywords", + "keywords", + NULL, + G_PARAM_READABLE); g_object_class_install_properties (gobject_class, N_PROPS, properties); } @@ -691,6 +703,21 @@ filter_demo (GtkDemo *demo) if (g_str_match_string (search_needle[i], demo->title, TRUE)) continue; + if (demo->keywords) + { + int j; + gboolean found = FALSE; + + for (j = 0; !found && demo->keywords[j]; j++) + { + if (strstr (demo->keywords[j], search_needle[i])) + found = TRUE; + } + + if (found) + continue; + } + return FALSE; } @@ -761,7 +788,7 @@ demo_search_changed_cb (GtkSearchEntry *entry, g_clear_pointer (&search_needle, g_strfreev); if (text && *text) - search_needle = g_strsplit (text, " ", 0); + search_needle = g_str_tokenize_and_fold (text, NULL, NULL); gtk_filter_changed (filter, GTK_FILTER_CHANGE_DIFFERENT); } @@ -779,6 +806,7 @@ create_demo_model (void) d->name = demo->name; d->title = demo->title; + d->keywords = demo->keywords; d->filename = demo->filename; d->func = demo->func; @@ -794,6 +822,7 @@ create_demo_model (void) child->name = children->name; child->title = children->title; + child->keywords = children->keywords; child->filename = children->filename; child->func = children->func;