2007-06-30 Johan Dahlin <jdahlin@async.com.br>
+ * gtk/gtkbuilderparser.c: (_get_type_by_symbol), (parse_object),
+ (parse_child):
+ * tests/buildertest.c: (test_types):
+ Move type-func to <object> instead of <child>, add a test to
+ make sure that it works as desired, #452463
+
* gtk/gtkbuilder.c: (gtk_builder_value_from_string_type):
* gtk/gtkbuilderparser.c: (_gtk_builder_parse_boolean),
(parse_property), (parse_signal):
return object;
}
+static gchar *
+_get_type_by_symbol (const gchar* symbol)
+{
+ static GModule *module = NULL;
+ GTypeGetFunc func;
+ GType type;
+
+ if (!module)
+ module = g_module_open (NULL, 0);
+
+ if (!g_module_symbol (module, symbol, (gpointer)&func))
+ return NULL;
+
+ type = func ();
+ if (type == G_TYPE_INVALID)
+ return NULL;
+
+ return g_strdup (g_type_name (type));
+}
+
static void
parse_object (ParserData *data,
const gchar *element_name,
object_id = g_strdup (values[i]);
else if (strcmp (names[i], "constructor") == 0)
constructor = g_strdup (values[i]);
+ else if (strcmp (names[i], "type-func") == 0)
+ {
+ /* Call the GType function, and return the name of the GType,
+ * it's guaranteed afterwards that g_type_from_name on the name
+ * will return our GType
+ */
+ object_class = _get_type_by_symbol (values[i]);
+ if (!object_class)
+ {
+ g_set_error (error, GTK_BUILDER_ERROR,
+ GTK_BUILDER_ERROR_INVALID_TYPE_FUNCTION,
+ _("Invalid type function: `%s'"),
+ values[i]);
+ return;
+ }
+ }
else
{
error_invalid_attribute (data, element_name, names[i], error);
g_slice_free (ObjectInfo, info);
}
-static gchar *
-_get_type_by_symbol (const gchar* symbol)
-{
- static GModule *module = NULL;
- GTypeGetFunc func;
- GType type;
-
- if (!module)
- module = g_module_open (NULL, 0);
-
- if (!g_module_symbol (module, symbol, (gpointer)&func))
- return NULL;
-
- type = func ();
- if (type == G_TYPE_INVALID)
- return NULL;
-
- return g_strdup (g_type_name (type));
-}
-
static void
parse_child (ParserData *data,
const gchar *element_name,
child_info->type = g_strdup (values[i]);
else if (strcmp (names[i], "internal-child") == 0)
child_info->internal_child = g_strdup (values[i]);
- else if (strcmp (names[i], "type-func") == 0)
- {
- child_info->type = _get_type_by_symbol (values[i]);
- if (!child_info->type)
- {
- g_set_error (error, GTK_BUILDER_ERROR,
- GTK_BUILDER_ERROR_INVALID_TYPE_FUNCTION,
- _("Invalid type function: `%s'"),
- values[i]);
- return;
- }
- }
else
error_invalid_attribute (data, element_name, names[i], error);
}
" <object class=\"GtkWindow\" id=\"window\"/>"
" <object class=\"GtkUIManager\" id=\"uimanager\"/>"
"</interface>";
+ const gchar buffer2[] =
+ "<interface>"
+ " <object type-func=\"gtk_window_get_type\" id=\"window\"/>"
+ "</interface>";
+ const gchar buffer3[] =
+ "<interface>"
+ " <object type-func=\"xxx_invalid_get_type_function\" id=\"window\"/>"
+ "</interface>";
GtkBuilder *builder;
+ GObject *window;
+ GError *error;
builder = builder_new_from_string (buffer, -1, NULL);
gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "dialog")));
gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "window")));
g_object_unref (builder);
+
+ builder = builder_new_from_string (buffer2, -1, NULL);
+ window = gtk_builder_get_object (builder, "window");
+ g_assert (window != NULL);
+ g_assert (GTK_IS_WINDOW (window));
+ gtk_widget_destroy (GTK_WIDGET (window));
+ g_object_unref (builder);
+ error = NULL;
+ builder = gtk_builder_new ();
+ gtk_builder_add_from_string (builder, buffer3, -1, &error);
+ g_assert (error != NULL);
+ g_return_val_if_fail (error->domain == GTK_BUILDER_ERROR, FALSE);
+ g_return_val_if_fail (error->code == GTK_BUILDER_ERROR_INVALID_TYPE_FUNCTION, FALSE);
+ g_error_free (error);
+ g_object_unref (builder);
+
return TRUE;
}