[gtk+/composite-templates: 7/10] Added template_id parameter to gtk_builder_add_to_parent_*() functions This makes it more consistent
- From: Juan Pablo Ugarte <jpu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/composite-templates: 7/10] Added template_id parameter to gtk_builder_add_to_parent_*() functions This makes it more consistent
- Date: Mon, 12 Nov 2012 18:09:48 +0000 (UTC)
commit a706ec1d8a87a2e74baf1ea9831bb7543d8d0c7e
Author: Juan Pablo Ugarte <juanpablougarte gmail com>
Date: Fri Nov 2 12:05:53 2012 -0300
Added template_id parameter to gtk_builder_add_to_parent_*() functions
This makes it more consistent since now you have to name the template
and let you have more than one template in a file.
gtk/gtkbuilder.c | 317 +++++++++++++++++++++--------------------------
gtk/gtkbuilder.h | 5 +-
gtk/gtkbuilderparser.c | 164 ++++++++++++++----------
gtk/gtkbuilderprivate.h | 16 ++-
gtk/gtkcontainer.c | 11 ++-
5 files changed, 259 insertions(+), 254 deletions(-)
---
diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c
index f306d75..80be5e9 100644
--- a/gtk/gtkbuilder.c
+++ b/gtk/gtkbuilder.c
@@ -894,6 +894,43 @@ gtk_builder_new (void)
return g_object_new (GTK_TYPE_BUILDER, NULL);
}
+static guint
+gtk_builder_add_from_file_real (GtkBuilder *builder,
+ GObject *parent,
+ const gchar *template_id,
+ const gchar *filename,
+ gchar **object_ids,
+ GError **error)
+{
+ GError *tmp_error = NULL;
+ gchar *buffer;
+ gsize length;
+
+ if (!g_file_get_contents (filename, &buffer, &length, &tmp_error))
+ {
+ g_propagate_error (error, tmp_error);
+ return 0;
+ }
+
+ g_free (builder->priv->filename);
+ g_free (builder->priv->resource_prefix);
+ builder->priv->filename = g_strdup (filename);
+ builder->priv->resource_prefix = NULL;
+
+ _gtk_builder_parser_parse_buffer (builder, parent, template_id, filename,
+ buffer, length, object_ids, &tmp_error);
+
+ g_free (buffer);
+
+ if (tmp_error != NULL)
+ {
+ g_propagate_error (error, tmp_error);
+ return 0;
+ }
+
+ return 1;
+}
+
/**
* gtk_builder_add_from_file:
* @builder: a #GtkBuilder
@@ -916,20 +953,25 @@ gtk_builder_add_from_file (GtkBuilder *builder,
const gchar *filename,
GError **error)
{
- return gtk_builder_add_to_parent_from_file (builder, NULL, filename, error);
+ g_return_val_if_fail (GTK_IS_BUILDER (builder), 0);
+ g_return_val_if_fail (filename != NULL, 0);
+ g_return_val_if_fail (error == NULL || *error == NULL, 0);
+
+ return gtk_builder_add_from_file_real (builder, NULL, NULL, filename,
+ NULL, error);
}
/**
* gtk_builder_add_to_parent_from_file:
* @builder: a #GtkBuilder
- * @parent: the parent object to be assumed in context while parsing the file
+ * @parent: the parent container where children will be added, or %NULL
+ * @template_id: the template id to use, or %NULL
* @filename: the name of the file to parse
* @error: (allow-none): return location for an error, or %NULL
*
* Like gtk_builder_add_from_file() except the format will expect
- * <child> instead of <object> as its first elements and expose
- * @parent in the build context, children defined in the UI fragment
- * will be added to @parent.
+ * <template> instead of <object> with id @template_id.
+ * The children defined in the UI fragment will be added to @parent.
*
* Returns: A positive value on success, 0 if an error occurred
*
@@ -938,44 +980,18 @@ gtk_builder_add_from_file (GtkBuilder *builder,
guint
gtk_builder_add_to_parent_from_file (GtkBuilder *builder,
GObject *parent,
+ const gchar *template_id,
const gchar *filename,
GError **error)
{
- gchar *buffer;
- gsize length;
- GError *tmp_error;
-
g_return_val_if_fail (GTK_IS_BUILDER (builder), 0);
+ g_return_val_if_fail (GTK_IS_CONTAINER (parent), 0);
+ g_return_val_if_fail (template_id != NULL, 0);
g_return_val_if_fail (filename != NULL, 0);
g_return_val_if_fail (error == NULL || *error == NULL, 0);
- tmp_error = NULL;
-
- if (!g_file_get_contents (filename, &buffer, &length, &tmp_error))
- {
- g_propagate_error (error, tmp_error);
- return 0;
- }
-
- g_free (builder->priv->filename);
- g_free (builder->priv->resource_prefix);
- builder->priv->filename = g_strdup (filename);
- builder->priv->resource_prefix = NULL;
-
- _gtk_builder_parser_parse_buffer (builder, parent, filename,
- buffer, length,
- NULL,
- &tmp_error);
-
- g_free (buffer);
-
- if (tmp_error != NULL)
- {
- g_propagate_error (error, tmp_error);
- return 0;
- }
-
- return 1;
+ return gtk_builder_add_from_file_real (builder, parent, template_id,
+ filename, NULL, error);
}
/**
@@ -1009,34 +1025,55 @@ gtk_builder_add_objects_from_file (GtkBuilder *builder,
gchar **object_ids,
GError **error)
{
- gchar *buffer;
- gsize length;
- GError *tmp_error;
-
g_return_val_if_fail (GTK_IS_BUILDER (builder), 0);
g_return_val_if_fail (filename != NULL, 0);
g_return_val_if_fail (object_ids != NULL && object_ids[0] != NULL, 0);
g_return_val_if_fail (error == NULL || *error == NULL, 0);
+ return gtk_builder_add_from_file_real (builder, NULL, NULL, filename,
+ object_ids, error);
+}
+
+static guint
+gtk_builder_add_from_resource_real (GtkBuilder *builder,
+ GObject *parent,
+ const gchar *template_id,
+ const gchar *path,
+ gchar **object_ids,
+ GError **error)
+{
+ GError *tmp_error;
+ GBytes *data;
+ char *filename_for_errors;
+ char *slash;
+
tmp_error = NULL;
- if (!g_file_get_contents (filename, &buffer, &length, &tmp_error))
+ data = g_resources_lookup_data (path, 0, &tmp_error);
+ if (data == NULL)
{
g_propagate_error (error, tmp_error);
return 0;
}
-
+
g_free (builder->priv->filename);
g_free (builder->priv->resource_prefix);
- builder->priv->filename = g_strdup (filename);
- builder->priv->resource_prefix = NULL;
+ builder->priv->filename = g_strdup (".");
- _gtk_builder_parser_parse_buffer (builder, NULL, filename,
- buffer, length,
- object_ids,
- &tmp_error);
+ slash = strrchr (path, '/');
+ if (slash != NULL)
+ builder->priv->resource_prefix = g_strndup (path, slash - path + 1);
+ else
+ builder->priv->resource_prefix = g_strdup ("/");
- g_free (buffer);
+ filename_for_errors = g_strconcat ("<resource>", path, NULL);
+
+ _gtk_builder_parser_parse_buffer (builder, parent, template_id, filename_for_errors,
+ g_bytes_get_data (data, NULL), g_bytes_get_size (data),
+ object_ids, &tmp_error);
+
+ g_free (filename_for_errors);
+ g_bytes_unref (data);
if (tmp_error != NULL)
{
@@ -1069,20 +1106,26 @@ gtk_builder_add_from_resource (GtkBuilder *builder,
const gchar *resource_path,
GError **error)
{
- return gtk_builder_add_to_parent_from_resource (builder, NULL, resource_path, error);
+ g_return_val_if_fail (GTK_IS_BUILDER (builder), 0);
+ g_return_val_if_fail (resource_path != NULL, 0);
+ g_return_val_if_fail (error == NULL || *error == NULL, 0);
+
+ return gtk_builder_add_from_resource_real (builder, NULL, NULL,
+ resource_path, NULL,
+ error);
}
/**
* gtk_builder_add_to_parent_from_resource:
* @builder: a #GtkBuilder
- * @parent: the parent object to be assumed in context while parsing the file
- * @path: the resource path to parse
+ * @parent: the parent container where children will be added, or %NULL
+ * @template_id: the template id to use, or %NULL
+ * @resource_path: the resource path to parse
* @error: (allow-none): return location for an error, or %NULL
*
- * Like gtk_builder_add_from_file() except the format will expect
- * <child> instead of <object> as its first elements and expose
- * @parent in the build context, children defined in the UI fragment
- * will be added to @parent.
+ * Like gtk_builder_add_from_resource() except the format will expect
+ * <template> instead of <object> with id @template_id.
+ * The children defined in the UI fragment will be added to @parent.
*
* Returns: A positive value on success, 0 if an error occurred
*
@@ -1091,54 +1134,18 @@ gtk_builder_add_from_resource (GtkBuilder *builder,
guint
gtk_builder_add_to_parent_from_resource (GtkBuilder *builder,
GObject *parent,
- const gchar *path,
+ const gchar *template_id,
+ const gchar *resource_path,
GError **error)
{
- GError *tmp_error;
- GBytes *data;
- char *filename_for_errors;
- char *slash;
-
g_return_val_if_fail (GTK_IS_BUILDER (builder), 0);
- g_return_val_if_fail (path != NULL, 0);
+ g_return_val_if_fail (GTK_IS_CONTAINER (parent), 0);
+ g_return_val_if_fail (template_id != NULL, 0);
+ g_return_val_if_fail (resource_path != NULL, 0);
g_return_val_if_fail (error == NULL || *error == NULL, 0);
- tmp_error = NULL;
-
- data = g_resources_lookup_data (path, 0, &tmp_error);
- if (data == NULL)
- {
- g_propagate_error (error, tmp_error);
- return 0;
- }
-
- g_free (builder->priv->filename);
- g_free (builder->priv->resource_prefix);
- builder->priv->filename = g_strdup (".");
-
- slash = strrchr (path, '/');
- if (slash != NULL)
- builder->priv->resource_prefix = g_strndup (path, slash - path + 1);
- else
- builder->priv->resource_prefix = g_strdup ("/");
-
- filename_for_errors = g_strconcat ("<resource>", path, NULL);
-
- _gtk_builder_parser_parse_buffer (builder, parent, filename_for_errors,
- g_bytes_get_data (data, NULL), g_bytes_get_size (data),
- NULL,
- &tmp_error);
-
- g_free (filename_for_errors);
- g_bytes_unref (data);
-
- if (tmp_error != NULL)
- {
- g_propagate_error (error, tmp_error);
- return 0;
- }
-
- return 1;
+ return gtk_builder_add_from_resource_real (builder, parent, template_id,
+ resource_path, NULL, error);
}
/**
@@ -1172,46 +1179,34 @@ gtk_builder_add_objects_from_resource (GtkBuilder *builder,
gchar **object_ids,
GError **error)
{
- GError *tmp_error;
- GBytes *data;
- char *filename_for_errors;
- char *slash;
-
g_return_val_if_fail (GTK_IS_BUILDER (builder), 0);
g_return_val_if_fail (resource_path != NULL, 0);
g_return_val_if_fail (object_ids != NULL && object_ids[0] != NULL, 0);
g_return_val_if_fail (error == NULL || *error == NULL, 0);
- tmp_error = NULL;
+ return gtk_builder_add_from_resource_real (builder, NULL, NULL,
+ resource_path, object_ids,
+ error);
+}
- data = g_resources_lookup_data (resource_path, 0, &tmp_error);
- if (data == NULL)
- {
- g_propagate_error (error, tmp_error);
- return 0;
- }
+static guint
+gtk_builder_add_from_string_real (GtkBuilder *builder,
+ GObject *parent,
+ const gchar *template_id,
+ const gchar *buffer,
+ gsize length,
+ gchar **object_ids,
+ GError **error)
+{
+ GError *tmp_error = NULL;
g_free (builder->priv->filename);
g_free (builder->priv->resource_prefix);
builder->priv->filename = g_strdup (".");
+ builder->priv->resource_prefix = NULL;
- slash = strrchr (resource_path, '/');
- if (slash != NULL)
- builder->priv->resource_prefix =
- g_strndup (resource_path, slash - resource_path + 1);
- else
- builder->priv->resource_prefix =
- g_strdup ("/");
-
- filename_for_errors = g_strconcat ("<resource>", resource_path, NULL);
-
- _gtk_builder_parser_parse_buffer (builder, NULL, filename_for_errors,
- g_bytes_get_data (data, NULL), g_bytes_get_size (data),
- object_ids,
- &tmp_error);
- g_free (filename_for_errors);
- g_bytes_unref (data);
-
+ _gtk_builder_parser_parse_buffer (builder, parent, template_id, "<input>",
+ buffer, length, object_ids, &tmp_error);
if (tmp_error != NULL)
{
g_propagate_error (error, tmp_error);
@@ -1244,22 +1239,28 @@ gtk_builder_add_from_string (GtkBuilder *builder,
gsize length,
GError **error)
{
- return gtk_builder_add_to_parent_from_string (builder, NULL, buffer, length, error);
+ g_return_val_if_fail (GTK_IS_BUILDER (builder), 0);
+ g_return_val_if_fail (buffer != NULL, 0);
+ g_return_val_if_fail (error == NULL || *error == NULL, 0);
+
+ return gtk_builder_add_from_string_real (builder, NULL, NULL,
+ buffer, length,
+ NULL, error);
}
/**
* gtk_builder_add_to_parent_from_string:
* @builder: a #GtkBuilder
- * @parent: the parent object to be assumed in context while parsing
+ * @parent: the parent container where children will be added, or %NULL
+ * @template_id: the template id to use, or %NULL
* @buffer: the string to parse
* @length: the length of @buffer (may be -1 if @buffer is nul-terminated)
* @error: (allow-none): return location for an error, or %NULL
*
* Like gtk_builder_add_from_string() except the format will expect
- * <child> instead of <object> as its first elements and expose
- * @parent in the build context, children defined in the UI fragment
- * will be added to @parent.
+ * <template> instead of <object> with id @template_id.
+ * The children defined in the UI fragment will be added to @parent.
*
* Returns: A positive value on success, 0 if an error occurred
*
@@ -1268,34 +1269,20 @@ gtk_builder_add_from_string (GtkBuilder *builder,
guint
gtk_builder_add_to_parent_from_string (GtkBuilder *builder,
GObject *parent,
+ const gchar *template_id,
const gchar *buffer,
gsize length,
GError **error)
{
- GError *tmp_error;
-
g_return_val_if_fail (GTK_IS_BUILDER (builder), 0);
+ g_return_val_if_fail (GTK_IS_CONTAINER (parent), 0);
+ g_return_val_if_fail (template_id != NULL, 0);
g_return_val_if_fail (buffer != NULL, 0);
g_return_val_if_fail (error == NULL || *error == NULL, 0);
- tmp_error = NULL;
-
- g_free (builder->priv->filename);
- g_free (builder->priv->resource_prefix);
- builder->priv->filename = g_strdup (".");
- builder->priv->resource_prefix = NULL;
-
- _gtk_builder_parser_parse_buffer (builder, parent, "<input>",
- buffer, length,
- NULL,
- &tmp_error);
- if (tmp_error != NULL)
- {
- g_propagate_error (error, tmp_error);
- return 0;
- }
-
- return 1;
+ return gtk_builder_add_from_string_real (builder, parent, template_id,
+ buffer, length,
+ NULL, error);
}
/**
@@ -1330,32 +1317,14 @@ gtk_builder_add_objects_from_string (GtkBuilder *builder,
gchar **object_ids,
GError **error)
{
- GError *tmp_error;
-
g_return_val_if_fail (GTK_IS_BUILDER (builder), 0);
g_return_val_if_fail (buffer != NULL, 0);
g_return_val_if_fail (object_ids != NULL && object_ids[0] != NULL, 0);
g_return_val_if_fail (error == NULL || *error == NULL, 0);
- tmp_error = NULL;
-
- g_free (builder->priv->filename);
- g_free (builder->priv->resource_prefix);
- builder->priv->filename = g_strdup (".");
- builder->priv->resource_prefix = NULL;
-
- _gtk_builder_parser_parse_buffer (builder, NULL, "<input>",
- buffer, length,
- object_ids,
- &tmp_error);
-
- if (tmp_error != NULL)
- {
- g_propagate_error (error, tmp_error);
- return 0;
- }
-
- return 1;
+ return gtk_builder_add_from_string_real (builder, NULL, NULL,
+ buffer, length,
+ object_ids, error);
}
/**
diff --git a/gtk/gtkbuilder.h b/gtk/gtkbuilder.h
index 77fc0a8..dc22f8d 100644
--- a/gtk/gtkbuilder.h
+++ b/gtk/gtkbuilder.h
@@ -142,16 +142,19 @@ guint gtk_builder_add_objects_from_string (GtkBuilder *builder,
GError **error);
guint gtk_builder_add_to_parent_from_file (GtkBuilder *builder,
GObject *parent,
+ const gchar *template_id,
const gchar *filename,
GError **error);
guint gtk_builder_add_to_parent_from_string (GtkBuilder *builder,
GObject *parent,
+ const gchar *template_id,
const gchar *buffer,
gsize length,
GError **error);
guint gtk_builder_add_to_parent_from_resource (GtkBuilder *builder,
GObject *parent,
- const gchar *path,
+ const gchar *template_id,
+ const gchar *resource_path,
GError **error);
GObject* gtk_builder_get_object (GtkBuilder *builder,
const gchar *name);
diff --git a/gtk/gtkbuilderparser.c b/gtk/gtkbuilderparser.c
index a006664..914f566 100644
--- a/gtk/gtkbuilderparser.c
+++ b/gtk/gtkbuilderparser.c
@@ -327,8 +327,9 @@ parse_object (GMarkupParseContext *context,
GType object_type = G_TYPE_INVALID;
ObjectInfo *object_info;
ChildInfo *child_info;
- gchar *object_id = NULL;
- gchar *constructor = NULL;
+ const gchar *object_class = NULL;
+ const gchar *object_id = NULL;
+ const gchar *constructor = NULL;
gint i, line, line2;
child_info = state_peek_info (data, ChildInfo);
@@ -341,12 +342,11 @@ parse_object (GMarkupParseContext *context,
for (i = 0; names[i] != NULL; i++)
{
if (strcmp (names[i], "class") == 0)
- /* Make sure the class is initialized so we have intern string available */
- object_type = gtk_builder_get_type_from_name (data->builder, values[i]);
+ object_class = values[i];
else if (strcmp (names[i], "id") == 0)
- object_id = g_strdup (values[i]);
+ object_id = values[i];
else if (strcmp (names[i], "constructor") == 0)
- constructor = g_strdup (values[i]);
+ constructor = values[i];
else if (strcmp (names[i], "type-func") == 0)
{
/* Call the GType function, and return the name of the GType,
@@ -371,7 +371,7 @@ parse_object (GMarkupParseContext *context,
}
}
- if (object_type == G_TYPE_INVALID)
+ if (object_type == G_TYPE_INVALID && !object_class)
{
error_missing_attribute (data, element_name, "class", error);
return;
@@ -383,6 +383,20 @@ parse_object (GMarkupParseContext *context,
return;
}
+ if (object_type == G_TYPE_INVALID)
+ {
+ /* Make sure the class is initialized so we have intern string available */
+ object_type = gtk_builder_get_type_from_name (data->builder, object_class);
+
+ if (object_type == G_TYPE_INVALID)
+ {
+ g_set_error (error, GTK_BUILDER_ERROR,
+ GTK_BUILDER_ERROR_INVALID_VALUE,
+ _("Invalid class: '%s'"), object_class);
+ return;
+ }
+ }
+
++data->cur_object_level;
/* check if we reached a requested object (if it is specified) */
@@ -400,16 +414,16 @@ parse_object (GMarkupParseContext *context,
}
else
{
- g_free (object_id);
- g_free (constructor);
return;
}
}
+ else if (data->template_object && !data->inside_requested_template)
+ return;
object_info = g_slice_new0 (ObjectInfo);
object_info->object_type = object_type;
- object_info->id = object_id;
- object_info->constructor = constructor;
+ object_info->id = g_strdup (object_id);
+ object_info->constructor = g_strdup (constructor);
state_push (data, object_info);
object_info->tag.name = element_name;
@@ -680,16 +694,8 @@ parse_template (ParserData *data,
const gchar *parent_class = NULL;
const gchar *class_name = NULL;
const gchar *id = NULL;
- GType parent_type, class_type;
- ObjectInfo *object_info;
gint i;
- if (parent == NULL)
- {
- error_invalid_tag (data, element_name, NULL, error);
- return;
- }
-
for (i = 0; names[i] != NULL; i++)
{
if (strcmp (names[i], "class") == 0)
@@ -711,58 +717,62 @@ parse_template (ParserData *data,
return;
}
- if (!parent_class)
- {
- error_missing_attribute (data, element_name, "parent", error);
- return;
- }
-
if (!id)
{
error_missing_attribute (data, element_name, "id", error);
return;
}
- if (strcmp (id, "this"))
+ if (parent)
{
- error_generic (error, GTK_BUILDER_ERROR_INVALID_VALUE, data,
- element_name, "%s template should be named 'this' not %s '%s'",
- class_name, id);
- return;
- }
+ const gchar *template_name= _gtk_builder_object_get_name (parent);
+ GType class_type, parent_type = G_OBJECT_TYPE (parent);
+ ObjectInfo *object_info;
- if ((class_type = g_type_from_name (class_name)) == G_TYPE_INVALID)
- {
- error_generic (error, GTK_BUILDER_ERROR_TEMPLATE_CLASS_MISMATCH, data,
- element_name, "invalid class type found '%s'", class_name);
- return;
- }
+ if (!data->inside_requested_template && g_strcmp0 (template_name, id) == 0)
+ data->inside_requested_template = TRUE;
+ else
+ return;
- parent_type = G_OBJECT_TYPE (parent);
-
- if (!g_type_is_a (parent_type, class_type))
- {
- error_generic (error, GTK_BUILDER_ERROR_TEMPLATE_CLASS_MISMATCH, data,
- element_name, "this template is for a class type %s not for %s",
- class_name, G_OBJECT_TYPE_NAME (parent));
- return;
- }
+ if (!(class_type = g_type_from_name (class_name)))
+ {
+ error_generic (error, GTK_BUILDER_ERROR_TEMPLATE_CLASS_MISMATCH, data,
+ element_name, "invalid class type found '%s'", class_name);
+ return;
+ }
+
+ if (!g_type_is_a (parent_type, class_type))
+ {
+ error_generic (error, GTK_BUILDER_ERROR_TEMPLATE_CLASS_MISMATCH, data,
+ element_name, "this template is for a class type %s not for %s",
+ class_name, G_OBJECT_TYPE_NAME (parent));
+ return;
+ }
- if (!g_type_is_a (class_type, g_type_from_name (parent_class)))
+ 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 = parent;
+ object_info->object_type = parent_type;
+ object_info->id = g_strdup (_gtk_builder_object_get_name (parent));
+ object_info->tag.name = "object";
+
+ state_push (data, object_info);
+ }
+ else
{
- error_generic (error, GTK_BUILDER_ERROR_TEMPLATE_CLASS_MISMATCH, data,
- element_name, "class %s should derive from parent %s",
- class_name, parent_class);
+ error_invalid_tag (data, element_name, NULL, error);
return;
}
-
- object_info = g_slice_new0 (ObjectInfo);
- object_info->object = parent;
- object_info->object_type = parent_type;
- object_info->id = g_strdup (_gtk_builder_object_get_name (parent));
- object_info->tag.name = "object";
- state_push (data, object_info);
}
/* Called by GtkBuilder */
@@ -1010,6 +1020,13 @@ start_element (GMarkupParseContext *context,
if (strcmp (element_name, "requires") == 0)
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 (data->template_object && !data->inside_requested_template)
+ {
+ /* If outside a requested template, ignore this tag */
+ return;
+ }
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)
@@ -1027,8 +1044,6 @@ start_element (GMarkupParseContext *context,
parse_interface (data, element_name, names, values, error);
else if (strcmp (element_name, "menu") == 0)
_gtk_builder_menu_start (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, "placeholder") == 0)
{
/* placeholder has no special treatmeant, but it needs an
@@ -1100,9 +1115,10 @@ end_element (GMarkupParseContext *context,
else if (strcmp (element_name, "interface") == 0)
{
}
- else if (data->requested_objects && !data->inside_requested_object)
+ else if ((data->requested_objects && !data->inside_requested_object) ||
+ (data->template_object && !data->inside_requested_template))
{
- /* If outside a requested object, simply ignore this tag */
+ /* If outside a requested object or template, simply ignore this tag */
return;
}
else if (strcmp (element_name, "menu") == 0)
@@ -1193,7 +1209,7 @@ end_element (GMarkupParseContext *context,
}
else if (strcmp (element_name, "template") == 0)
{
- if (data->template_object)
+ if (data->template_object && data->inside_requested_template)
{
ObjectInfo *object_info = state_pop_info (data, ObjectInfo);
@@ -1208,6 +1224,8 @@ end_element (GMarkupParseContext *context,
free_object_info (object_info);
data->template_object = NULL;
+
+ data->inside_requested_template = FALSE;
}
}
else
@@ -1283,6 +1301,7 @@ static const GMarkupParser parser = {
void
_gtk_builder_parser_parse_buffer (GtkBuilder *builder,
GObject *parent,
+ const gchar *template_id,
const gchar *filename,
const gchar *buffer,
gsize length,
@@ -1306,13 +1325,6 @@ _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
data->domain = g_strdup (domain);
data->object_ids = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify)g_free, NULL);
-
- if (parent)
- {
- GTK_NOTE (BUILDER, g_print ("parsing with contextual parent %s ptr %p\n", G_OBJECT_TYPE_NAME (parent), parent));
- data->template_object = parent;
- }
-
data->requested_objects = NULL;
if (requested_objs)
{
@@ -1331,6 +1343,20 @@ _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
data->inside_requested_object = TRUE;
}
+ if (parent)
+ {
+ data->inside_requested_template = FALSE;
+
+ if (template_id)
+ {
+ GTK_NOTE (BUILDER, g_print ("parsing with contextual parent %s class %s ptr %p\n",
+ template_id, G_OBJECT_TYPE_NAME (parent), parent));
+
+ data->template_object = parent;
+ gtk_builder_expose_object (builder, template_id, parent);
+ }
+ }
+
data->ctx = g_markup_parse_context_new (&parser,
G_MARKUP_TREAT_CDATA_AS_TEXT,
data, NULL);
diff --git a/gtk/gtkbuilderprivate.h b/gtk/gtkbuilderprivate.h
index 9e4b292..eb7051d 100644
--- a/gtk/gtkbuilderprivate.h
+++ b/gtk/gtkbuilderprivate.h
@@ -110,18 +110,20 @@ typedef struct {
GHashTable *object_ids;
GObject *template_object;
+ gboolean inside_requested_template;
} ParserData;
typedef GType (*GTypeGetFunc) (void);
/* Things only GtkBuilder should use */
-void _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
- GObject *parent,
- const gchar *filename,
- const gchar *buffer,
- gsize length,
- gchar **requested_objs,
- GError **error);
+void _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
+ GObject *parent,
+ const gchar *template_id,
+ const gchar *filename,
+ const gchar *buffer,
+ gsize length,
+ gchar **requested_objs,
+ GError **error);
GObject * _gtk_builder_construct (GtkBuilder *builder,
ObjectInfo *info,
GError **error);
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c
index 20cd790..076c77c 100644
--- a/gtk/gtkcontainer.c
+++ b/gtk/gtkcontainer.c
@@ -1667,15 +1667,20 @@ gtk_container_constructor (GType type,
guint ret;
builder = gtk_builder_new ();
- gtk_builder_expose_object (builder, "this", object);
switch (cpriv->tmpl_type)
{
case TMPL_STRING:
- ret = gtk_builder_add_to_parent_from_string (builder, object, cpriv->tmpl, -1, &error);
+ ret = gtk_builder_add_to_parent_from_string (builder, object,
+ "this",
+ cpriv->tmpl,
+ -1, &error);
break;
case TMPL_RESOURCE:
- ret = gtk_builder_add_to_parent_from_resource (builder, object, cpriv->tmpl, &error);
+ ret = gtk_builder_add_to_parent_from_resource (builder, object,
+ "this",
+ cpriv->tmpl,
+ &error);
break;
default:
ret = 0;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]