diff options
author | Juan Pablo Ugarte <juanpablougarte@gmail.com> | 2012-12-10 11:23:01 -0300 |
---|---|---|
committer | Juan Pablo Ugarte <juanpablougarte@gmail.com> | 2012-12-10 11:24:47 -0300 |
commit | 13870e733cb1ea7ad7449e53b13434189e609a41 (patch) | |
tree | 5797131eae54f96c879ecc2ca71f7e336f91938d | |
parent | e0ce659f342e8e485a245ea40a34ff37bfbd2720 (diff) | |
download | gtk+-13870e733cb1ea7ad7449e53b13434189e609a41.tar.gz |
Renamed <template> tag with <external-object> and keep <template> tag for new inline type definitions
-rw-r--r-- | gtk/gtkbuilderparser.c | 163 | ||||
-rw-r--r-- | gtk/gtkbuilderprivate.h | 3 | ||||
-rw-r--r-- | gtk/gtkcontainer.c | 5 | ||||
-rw-r--r-- | gtk/tests/builder.c | 134 |
4 files changed, 172 insertions, 133 deletions
diff --git a/gtk/gtkbuilderparser.c b/gtk/gtkbuilderparser.c index 6ddd2108fb..ebb7f056c7 100644 --- a/gtk/gtkbuilderparser.c +++ b/gtk/gtkbuilderparser.c @@ -447,7 +447,8 @@ parse_object (GMarkupParseContext *context, return; } } - else if (data->template_level && !data->template_object) + else if ((data->in_external_object && !data->external_object) || + data->template_level) return; object_info = g_slice_new0 (ObjectInfo); @@ -683,10 +684,8 @@ parse_signal (ParserData *data, typedef struct { - const gchar *tmpl_class, *tmpl_id; - - gboolean tmpl_found, done; - + const gchar *tmpl_class; + gboolean found, done, in_tmpl; GString *xml; } TemplateParseData; @@ -705,21 +704,26 @@ extract_template_start_element (GMarkupParseContext *context, if (g_strcmp0 (element_name, "template") == 0) { - gboolean right_class = FALSE, right_id = FALSE; - for (i = 0; attribute_names[i]; i++) { if (!g_strcmp0 (attribute_names[i], "class")) - right_class = (g_strcmp0 (attribute_values[i], state->tmpl_class) == 0); - else if (!g_strcmp0 (attribute_names[i], "id")) - right_id = (g_strcmp0 (attribute_values[i], state->tmpl_id) == 0); + state->found = (g_strcmp0 (attribute_values[i], state->tmpl_class) == 0); } - if (right_class && right_id) - state->tmpl_found = TRUE; + if (state->found) + { + state->in_tmpl = TRUE; + g_string_append_printf (state->xml, "<external-object class=\"%s\" id=\"%s\">", + state->tmpl_class, + state->tmpl_class); + return; + } + else + g_string_append_printf (state->xml, "<%s", element_name); } + else + g_string_append_printf (state->xml, "<%s", element_name); - g_string_append_printf (state->xml, "<%s", element_name); for (i = 0; attribute_names[i]; i++) { g_string_append_printf (state->xml, " %s=\"%s\"", @@ -737,10 +741,16 @@ extract_template_end_element (GMarkupParseContext *context, TemplateParseData *state = user_data; if (state->done) return; - - g_string_append_printf (state->xml, "</%s>", element_name); - if (g_strcmp0 (element_name, "interface") == 0 && state->tmpl_found) + if (g_strcmp0 (element_name, "template") == 0 && state->in_tmpl) + { + state->in_tmpl = FALSE; + g_string_append (state->xml, "</external-object>"); + } + else + g_string_append_printf (state->xml, "</%s>", element_name); + + if (g_strcmp0 (element_name, "interface") == 0 && state->found) state->done = TRUE; } @@ -759,10 +769,10 @@ extract_template_text (GMarkupParseContext *context, } static gchar * -extract_template (const gchar *buffer, const gchar *class_name, const gchar *class_id) +extract_template (const gchar *buffer, const gchar *class_name) { GMarkupParser parser = { extract_template_start_element, extract_template_end_element, extract_template_text }; - TemplateParseData state = { class_name, class_id, FALSE, FALSE, g_string_new ("")}; + TemplateParseData state = { class_name, FALSE, FALSE, FALSE, g_string_new ("")}; GMarkupParseContext *context; context = g_markup_parse_context_new (&parser, @@ -790,20 +800,19 @@ typedef struct { GTypeInfo *info; gchar *tmpl; - gchar *id; } TmplClassData; static void composite_template_derived_class_init (gpointer g_class, gpointer class_data) { TmplClassData *data = class_data; - gtk_container_class_set_template_from_string (g_class, data->tmpl, data->id); + gtk_container_class_set_template_from_string (g_class, data->tmpl, + G_OBJECT_CLASS_NAME (g_class)); } static GType create_inline_type (GType parent_type, const gchar *class_name, - const gchar *class_id, const gchar *template_xml) { TmplClassData *tmpl; @@ -814,8 +823,7 @@ create_inline_type (GType parent_type, tmpl = g_new0 (TmplClassData, 1); tmpl->info = info = g_new0 (GTypeInfo, 1); - tmpl->tmpl = extract_template (template_xml, class_name, class_id); - tmpl->id = g_strdup (class_id); + tmpl->tmpl = extract_template (template_xml, class_name); info->class_size = query.class_size; info->class_init = composite_template_derived_class_init; @@ -834,9 +842,8 @@ parse_template (ParserData *data, { const gchar *parent_class = NULL; const gchar *class_name = NULL; - const gchar *id = NULL; const GSList *l, *p; - GObject *parent; + GType parent_type; gint i; data->template_level++; @@ -856,6 +863,61 @@ parse_template (ParserData *data, class_name = values[i]; else if (strcmp (names[i], "parent") == 0) parent_class = values[i]; + else + { + error_invalid_attribute (data, element_name, names[i], error); + return; + } + } + + if (!class_name) + { + error_missing_attribute (data, element_name, "class", error); + return; + } + + if (!parent_class) + { + error_missing_attribute (data, element_name, "parent", error); + return; + } + + if (g_type_from_name (class_name)) + { + error_generic (error, GTK_BUILDER_ERROR_TEMPLATE_CLASS_MISMATCH, data, + element_name, "template class '%s' already registered", class_name); + return; + } + + if (!(parent_type = gtk_builder_get_type_from_name (data->builder, parent_class))) + { + error_generic (error, GTK_BUILDER_ERROR_TEMPLATE_CLASS_MISMATCH, data, + element_name, "invalid parent class type found '%s'", parent_class); + return; + } + + /* Generate inline type */ + create_inline_type (parent_type, class_name, data->buffer); +} + +static void +parse_external_object (ParserData *data, + const gchar *element_name, + const gchar **names, + const gchar **values, + GError **error) +{ + const gchar *class_name = NULL; + const gchar *id = NULL; + GObject *parent; + gint i; + + data->in_external_object = TRUE; + + for (i = 0; names[i] != NULL; i++) + { + if (strcmp (names[i], "class") == 0) + class_name = values[i]; else if (strcmp (names[i], "id") == 0) id = values[i]; else @@ -898,18 +960,9 @@ parse_template (ParserData *data, return; } - if (parent_class && - !g_type_is_a (class_type, g_type_from_name (parent_class))) - { - error_generic (error, GTK_BUILDER_ERROR_TEMPLATE_CLASS_MISMATCH, data, - element_name, "class %s should derive from parent %s", - class_name, parent_class); - return; - } - /* push parent to build its children from the template */ object_info = g_slice_new0 (ObjectInfo); - object_info->object = data->template_object = parent; + object_info->object = data->external_object = parent; object_info->object_type = parent_type; object_info->id = g_strdup (_gtk_builder_object_get_name (parent)); object_info->tag.name = "object"; @@ -918,27 +971,6 @@ parse_template (ParserData *data, parser_add_object_id (data, object_info->id, error); } - else if (parent_class) - { - GType parent_type; - - if (g_type_from_name (class_name)) - { - error_generic (error, GTK_BUILDER_ERROR_TEMPLATE_CLASS_MISMATCH, data, - element_name, "template class '%s' already registered", class_name); - return; - } - - if (!(parent_type = gtk_builder_get_type_from_name (data->builder, parent_class))) - { - error_generic (error, GTK_BUILDER_ERROR_TEMPLATE_CLASS_MISMATCH, data, - element_name, "invalid parent class type found '%s'", parent_class); - return; - } - - /* Generate inline type */ - create_inline_type (parent_type, class_name, id, data->buffer); - } } /* Called by GtkBuilder */ @@ -1188,10 +1220,13 @@ start_element (GMarkupParseContext *context, parse_requires (data, element_name, names, values, error); else if (strcmp (element_name, "template") == 0) parse_template (data, element_name, names, values, error); + else if (strcmp (element_name, "external-object") == 0) + parse_external_object (data, element_name, names, values, error); else if (strcmp (element_name, "object") == 0) parse_object (context, data, element_name, names, values, error); else if ((data->requested_objects && !data->inside_requested_object) || - (data->template_level && !data->template_object)) + (data->in_external_object && !data->external_object) || + data->template_level) { /* If outside a requested object, simply ignore this tag */ return; @@ -1280,9 +1315,12 @@ end_element (GMarkupParseContext *context, else if (strcmp (element_name, "template") == 0) { data->template_level--; - - /* Yes its a template! */ - if (data->template_object) + } + else if (strcmp (element_name, "external-object") == 0) + { + data->in_external_object = FALSE; + + if (data->external_object) { ObjectInfo *object_info = state_pop_info (data, ObjectInfo); @@ -1295,11 +1333,12 @@ end_element (GMarkupParseContext *context, _gtk_builder_add_signals (data->builder, object_info->signals); free_object_info (object_info); - data->template_object = NULL; + data->external_object = NULL; } } else if ((data->requested_objects && !data->inside_requested_object) || - (data->template_level && !data->template_object)) + (data->in_external_object && !data->external_object) || + data->template_level) { /* If outside a requested object or template, simply ignore this tag */ return; diff --git a/gtk/gtkbuilderprivate.h b/gtk/gtkbuilderprivate.h index 025dfdf418..f2aa6a1307 100644 --- a/gtk/gtkbuilderprivate.h +++ b/gtk/gtkbuilderprivate.h @@ -109,7 +109,8 @@ typedef struct { GHashTable *object_ids; - GObject *template_object; + GObject *external_object; + gint in_external_object; gint template_level; } ParserData; diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c index 90b800cd5f..8ea8b7aa8e 100644 --- a/gtk/gtkcontainer.c +++ b/gtk/gtkcontainer.c @@ -1471,9 +1471,8 @@ gtk_container_class_set_template_from_string (GtkContainerClass *container_class * Instances with an assigned template will have their children built at object * construct time. * - * The provided xml is expected to have a <template> tag instead of <object> - * with id=@template_id and an extra 'parent' property specifying from which type - * the new class derives from. + * The provided xml is expected to have a <external-object> tag instead of + * <object> with id=@template_id. * * Since: 3.8 */ diff --git a/gtk/tests/builder.c b/gtk/tests/builder.c index 7a516df2ab..30eb86c9b0 100644 --- a/gtk/tests/builder.c +++ b/gtk/tests/builder.c @@ -2715,8 +2715,58 @@ test_level_bar (void) g_object_unref (builder); } +static GObject *external_object = NULL, *external_object_swapped = NULL; + +void +on_button_clicked (GtkButton *button, GObject *data) +{ + external_object = data; +} + +void +on_button_clicked_swapped (GObject *data, GtkButton *button) +{ + external_object_swapped = data; +} + static void -test_template_real (gboolean use_add_objects) +test_expose_object (void) +{ + GtkBuilder *builder; + GError *error = NULL; + GtkWidget *image; + GObject *obj; + const gchar buffer[] = + "<interface>" + " <object class=\"GtkButton\" id=\"button\">" + " <property name=\"image\">external_image</property>" + " <signal name=\"clicked\" handler=\"on_button_clicked\" object=\"builder\" swapped=\"no\"/>" + " <signal name=\"clicked\" handler=\"on_button_clicked_swapped\" object=\"builder\"/>" + " </object>" + "</interface>"; + + image = gtk_image_new (); + builder = gtk_builder_new (); + gtk_builder_expose_object (builder, "external_image", G_OBJECT (image)); + gtk_builder_expose_object (builder, "builder", G_OBJECT (builder)); + gtk_builder_add_from_string (builder, buffer, -1, &error); + g_assert (error == NULL); + + obj = gtk_builder_get_object (builder, "button"); + g_assert (GTK_IS_BUTTON (obj)); + + g_assert (gtk_button_get_image (GTK_BUTTON (obj)) == image); + + /* Connect signals and fake clicked event */ + gtk_builder_connect_signals (builder, NULL); + gtk_button_clicked (GTK_BUTTON (obj)); + + g_assert (external_object == G_OBJECT (builder)); + g_assert (external_object_swapped == G_OBJECT (builder)); +} + +static void +test_external_object_real (gboolean use_add_objects) { GError *error = NULL; GtkBuilder *builder; @@ -2726,25 +2776,25 @@ test_template_real (gboolean use_add_objects) guint padding = 0; const gchar buffer[] = "<interface>\n" - " <template class=\"GtkGrid\" id=\"mygrid\">\n" + " <external-object class=\"GtkGrid\" id=\"mygrid\">\n" " <property name=\"visible\">True</property>\n" " <child>\n" " <object class=\"GtkLabel\" id=\"gridlabel\">\n" " <property name=\"visible\">True</property>\n" " </object>\n" " </child>\n" - " </template>\n" - /* This template should get ignored */ - " <template class=\"GtkGrid\" id=\"mygrid2\">\n" + " </external-object>\n" + /* This external_object should get ignored */ + " <external-object class=\"GtkGrid\" id=\"mygrid2\">\n" " <property name=\"visible\">True</property>\n" " <child>\n" " <object class=\"GtkLabel\" id=\"grid2label\">\n" " <property name=\"visible\">True</property>\n" " </object>\n" " </child>\n" - " </template>\n" - /* This is the template we are interested in! */ - " <template class=\"GtkBox\" id=\"mybox\">\n" + " </external-object>\n" + /* This is the external_object we are interested in! */ + " <external-object class=\"GtkBox\" id=\"mybox\">\n" " <property name=\"visible\">True</property>\n" " <property name=\"can_focus\">False</property>\n" " <property name=\"orientation\">vertical</property>\n" @@ -2776,7 +2826,7 @@ test_template_real (gboolean use_add_objects) " <property name=\"position\">1</property>\n" " </packing>\n" " </child>\n" - " </template>\n" + " </external-object>\n" " <object class=\"GtkWindow\" id=\"window\">" " <child>\n" " <object class=\"GtkLabel\" id=\"winlabel\">\n" @@ -2805,7 +2855,7 @@ test_template_real (gboolean use_add_objects) /* Check if requested object creation works */ g_assert (GTK_IS_WINDOW (gtk_builder_get_object (builder, "window"))); - /* Templates should be ignored if we requested a specific object */ + /* external objects should be ignored if we requested a specific object */ g_assert (gtk_builder_get_object (builder, "winlabel")); } else @@ -2839,20 +2889,20 @@ test_template_real (gboolean use_add_objects) } static void -test_template (void) +test_external_object (void) { - test_template_real (FALSE); - test_template_real (TRUE); + test_external_object_real (FALSE); + test_external_object_real (TRUE); } static void -test_inline_template () +test_template () { GError *error = NULL; GtkBuilder *builder; const gchar buffer[] = "<interface>\n" - " <template class=\"MyGtkGrid\" parent=\"GtkGrid\" id=\"mygrid_tmpl\">\n" + " <template class=\"MyGtkGrid\" parent=\"GtkGrid\">\n" " <property name=\"visible\">True</property>\n" " <child>\n" " <object class=\"GtkLabel\" id=\"gridlabel\">\n" @@ -2892,56 +2942,6 @@ test_inline_template () g_object_unref (builder); } -static GObject *external_object = NULL, *external_object_swapped = NULL; - -void -on_button_clicked (GtkButton *button, GObject *data) -{ - external_object = data; -} - -void -on_button_clicked_swapped (GObject *data, GtkButton *button) -{ - external_object_swapped = data; -} - -static void -test_expose_object (void) -{ - GtkBuilder *builder; - GError *error = NULL; - GtkWidget *image; - GObject *obj; - const gchar buffer[] = - "<interface>" - " <object class=\"GtkButton\" id=\"button\">" - " <property name=\"image\">external_image</property>" - " <signal name=\"clicked\" handler=\"on_button_clicked\" object=\"builder\" swapped=\"no\"/>" - " <signal name=\"clicked\" handler=\"on_button_clicked_swapped\" object=\"builder\"/>" - " </object>" - "</interface>"; - - image = gtk_image_new (); - builder = gtk_builder_new (); - gtk_builder_expose_object (builder, "external_image", G_OBJECT (image)); - gtk_builder_expose_object (builder, "builder", G_OBJECT (builder)); - gtk_builder_add_from_string (builder, buffer, -1, &error); - g_assert (error == NULL); - - obj = gtk_builder_get_object (builder, "button"); - g_assert (GTK_IS_BUTTON (obj)); - - g_assert (gtk_button_get_image (GTK_BUTTON (obj)) == image); - - /* Connect signals and fake clicked event */ - gtk_builder_connect_signals (builder, NULL); - gtk_button_clicked (GTK_BUTTON (obj)); - - g_assert (external_object == G_OBJECT (builder)); - g_assert (external_object_swapped == G_OBJECT (builder)); -} - int main (int argc, char **argv) { @@ -2990,9 +2990,9 @@ main (int argc, char **argv) g_test_add_func ("/Builder/MessageDialog", test_message_dialog); g_test_add_func ("/Builder/GMenu", test_gmenu); g_test_add_func ("/Builder/LevelBar", test_level_bar); - g_test_add_func ("/Builder/Template", test_template); - g_test_add_func ("/Builder/Inline Template", test_inline_template); g_test_add_func ("/Builder/Expose Object", test_expose_object); + g_test_add_func ("/Builder/External Object", test_external_object); + g_test_add_func ("/Builder/Template", test_template); return g_test_run(); } |