| /* Copyright 2015 Red Hat, Inc. |
| * |
| * GTK is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU Lesser General Public License as |
| * published by the Free Software Foundation; either version 2 of the |
| * License, or (at your option) any later version. |
| * |
| * GLib is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with GTK; see the file COPYING. If not, |
| * see <http://www.gnu.org/licenses/>. |
| * |
| * Author: Matthias Clasen |
| */ |
| |
| #include "config.h" |
| |
| #include "fake-scope.h" |
| #include "gtk-builder-tool.h" |
| |
| |
| #include <stdlib.h> |
| #include <string.h> |
| #include <errno.h> |
| |
| #include <glib/gi18n.h> |
| #include <glib/gprintf.h> |
| #include <glib/gstdio.h> |
| |
| /* {{{ Scope implementation */ |
| |
| struct _FakeScope |
| { |
| GtkBuilderCScope parent; |
| |
| GPtrArray *types; |
| GPtrArray *callbacks; |
| }; |
| |
| static GtkBuilderScopeInterface *parent_scope_iface; |
| |
| static void |
| dummy_cb (void) |
| { |
| } |
| |
| static GClosure * |
| fake_scope_create_closure (GtkBuilderScope *scope, |
| GtkBuilder *builder, |
| const char *function_name, |
| GtkBuilderClosureFlags flags, |
| GObject *object, |
| GError **error) |
| { |
| FakeScope *self = FAKE_SCOPE (scope); |
| GClosure *closure; |
| gboolean swapped = flags & GTK_BUILDER_CLOSURE_SWAPPED; |
| |
| g_ptr_array_add (self->callbacks, g_strdup (function_name)); |
| |
| if (object == NULL) |
| object = gtk_builder_get_current_object (builder); |
| |
| if (object) |
| { |
| if (swapped) |
| closure = g_cclosure_new_object_swap (dummy_cb, object); |
| else |
| closure = g_cclosure_new_object (dummy_cb, object); |
| } |
| else |
| { |
| if (swapped) |
| closure = g_cclosure_new_swap (dummy_cb, NULL, NULL); |
| else |
| closure = g_cclosure_new (dummy_cb, NULL, NULL); |
| } |
| |
| return closure; |
| } |
| |
| static GType |
| fake_scope_get_type_from_name (GtkBuilderScope *scope, |
| GtkBuilder *builder, |
| const char *type_name) |
| { |
| FakeScope *self = FAKE_SCOPE (scope); |
| GType type; |
| |
| type = parent_scope_iface->get_type_from_name (scope, builder, type_name); |
| |
| g_ptr_array_add (self->types, g_strdup (type_name)); |
| |
| return type; |
| } |
| |
| static GType |
| fake_scope_get_type_from_function (GtkBuilderScope *scope, |
| GtkBuilder *builder, |
| const char *function_name) |
| { |
| FakeScope *self = FAKE_SCOPE (scope); |
| GType type; |
| |
| type = parent_scope_iface->get_type_from_function (scope, builder, function_name); |
| |
| if (type != G_TYPE_INVALID) |
| g_ptr_array_add (self->types, g_strdup (g_type_name (type))); |
| |
| return type; |
| } |
| |
| static void |
| fake_scope_scope_init (GtkBuilderScopeInterface *iface) |
| { |
| parent_scope_iface = g_type_interface_peek_parent (iface); |
| |
| iface->get_type_from_name = fake_scope_get_type_from_name; |
| iface->get_type_from_function = fake_scope_get_type_from_function; |
| iface->create_closure = fake_scope_create_closure; |
| } |
| |
| G_DEFINE_TYPE_WITH_CODE (FakeScope, fake_scope, GTK_TYPE_BUILDER_CSCOPE, |
| G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDER_SCOPE, |
| fake_scope_scope_init)) |
| |
| static void |
| fake_scope_init (FakeScope *scope) |
| { |
| scope->types = g_ptr_array_new_with_free_func (g_free); |
| scope->callbacks = g_ptr_array_new_with_free_func (g_free); |
| } |
| |
| static void |
| fake_scope_finalize (GObject *object) |
| { |
| FakeScope *self = FAKE_SCOPE (object); |
| |
| g_ptr_array_unref (self->types); |
| g_ptr_array_unref (self->callbacks); |
| |
| G_OBJECT_CLASS (fake_scope_parent_class)->finalize (object); |
| } |
| |
| static void |
| fake_scope_class_init (FakeScopeClass *class) |
| { |
| G_OBJECT_CLASS (class)->finalize = fake_scope_finalize; |
| } |
| |
| /* }}} */ |
| /* {{{ API */ |
| |
| FakeScope * |
| fake_scope_new (void) |
| { |
| return g_object_new (fake_scope_get_type (), NULL); |
| } |
| |
| static int |
| cmp_strings (gconstpointer a, |
| gconstpointer b) |
| { |
| const char **aa = (const char **)a; |
| const char **bb = (const char **)b; |
| |
| return strcmp (*aa, *bb); |
| } |
| |
| static void |
| g_ptr_array_unique (GPtrArray *array, |
| GCompareFunc cmp) |
| { |
| int i; |
| |
| i = 1; |
| while (i < array->len) |
| { |
| gconstpointer *one = g_ptr_array_index (array, i - 1); |
| gconstpointer *two = g_ptr_array_index (array, i); |
| |
| if (cmp (&one, &two) == 0) |
| g_ptr_array_remove_index (array, i); |
| else |
| i++; |
| } |
| } |
| |
| GPtrArray * |
| fake_scope_get_types (FakeScope *self) |
| { |
| g_ptr_array_sort (self->types, cmp_strings); |
| g_ptr_array_unique (self->types, cmp_strings); |
| |
| return self->types; |
| } |
| |
| GPtrArray * |
| fake_scope_get_callbacks (FakeScope *self) |
| { |
| g_ptr_array_sort (self->callbacks, cmp_strings); |
| g_ptr_array_unique (self->callbacks, cmp_strings); |
| |
| return self->callbacks; |
| } |
| |
| /* }}} */ |
| |
| /* vim:set foldmethod=marker expandtab: */ |