diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt index 024645afd3..5bdeea2517 100644 --- a/docs/reference/gtk/gtk3-sections.txt +++ b/docs/reference/gtk/gtk3-sections.txt @@ -5438,6 +5438,7 @@ gtk_widget_path_iter_set_object_type gtk_widget_path_length gtk_widget_path_new gtk_widget_path_prepend_type +gtk_widget_path_to_string GTK_TYPE_WIDGET_PATH diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index 39485e0687..6352c4c1ec 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -3588,6 +3588,7 @@ gtk_widget_path_iter_set_object_type gtk_widget_path_length gtk_widget_path_new gtk_widget_path_prepend_type +gtk_widget_path_to_string gtk_widget_pop_composite_child gtk_widget_push_composite_child gtk_widget_queue_compute_expand diff --git a/gtk/gtkwidgetpath.c b/gtk/gtkwidgetpath.c index 177f7b866d..b59229a3ab 100644 --- a/gtk/gtkwidgetpath.c +++ b/gtk/gtkwidgetpath.c @@ -224,6 +224,90 @@ gtk_widget_path_length (const GtkWidgetPath *path) return path->elems->len; } +/** + * gtk_widget_path_to_string: + * @path: the path + * + * Dumps the widget path into a string representation. It tries to match + * the CSS style as closely as possible (Note that there might be paths + * that cannot be represented in CSS). + * + * The main use of this code is for debugging purposes, so that you can + * g_print() the path or dump it in a gdb session. + * + * Returns: A new string describing @path. + **/ +char * +gtk_widget_path_to_string (const GtkWidgetPath *path) +{ + GString *string; + guint i, j; + + g_return_val_if_fail (path != NULL, NULL); + + string = g_string_new (""); + + for (i = 0; i < path->elems->len; i++) + { + GtkPathElement *elem; + + elem = &g_array_index (path->elems, GtkPathElement, i); + + if (i > 0) + g_string_append_c (string, ' '); + + g_string_append (string, g_type_name (elem->type)); + + if (elem->name) + { + g_string_append_c (string, '('); + g_string_append (string, g_quark_to_string (elem->name)); + g_string_append_c (string, ')'); + } + + if (elem->classes) + { + for (j = 0; j < elem->classes->len; j++) + { + g_string_append_c (string, '.'); + g_string_append (string, g_quark_to_string (g_array_index (elem->classes, GQuark, j))); + } + } + + if (elem->regions) + { + GHashTableIter iter; + gpointer key, value; + + g_hash_table_iter_init (&iter, elem->regions); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + GtkRegionFlags flags = GPOINTER_TO_UINT (value); + static const char *flag_names[] = { + "even", + "odd", + "first", + "last", + "sorted" + }; + + g_string_append_c (string, ' '); + g_string_append (string, g_quark_to_string (GPOINTER_TO_UINT (key))); + for (j = 0; j < G_N_ELEMENTS(flag_names); j++) + { + if (flags & (1 << j)) + { + g_string_append_c (string, ':'); + g_string_append (string, flag_names[j]); + } + } + } + } + } + + return g_string_free (string, FALSE); +} + /** * gtk_widget_path_prepend_type: * @path: a #GtkWidgetPath diff --git a/gtk/gtkwidgetpath.h b/gtk/gtkwidgetpath.h index 2c9c981e41..a84c420548 100644 --- a/gtk/gtkwidgetpath.h +++ b/gtk/gtkwidgetpath.h @@ -39,6 +39,7 @@ GtkWidgetPath * gtk_widget_path_new (void); GtkWidgetPath * gtk_widget_path_copy (const GtkWidgetPath *path); void gtk_widget_path_free (GtkWidgetPath *path); +char * gtk_widget_path_to_string (const GtkWidgetPath *path); gint gtk_widget_path_length (const GtkWidgetPath *path); gint gtk_widget_path_append_type (GtkWidgetPath *path,