1 /*
2  * Copyright (c) 2013 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #include "config.h"
24 #include <glib/gi18n-lib.h>
25 
26 #include "object-hierarchy.h"
27 
28 #include "gtktreeselection.h"
29 #include "gtktreestore.h"
30 #include "gtktreeview.h"
31 #include "gtklabel.h"
32 
33 
34 enum
35 {
36   COLUMN_OBJECT_NAME
37 };
38 
39 struct _GtkInspectorObjectHierarchyPrivate
40 {
41   GtkTreeStore *model;
42   GtkTreeView *tree;
43 };
44 
G_DEFINE_TYPE_WITH_PRIVATE(GtkInspectorObjectHierarchy,gtk_inspector_object_hierarchy,GTK_TYPE_BOX)45 G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorObjectHierarchy, gtk_inspector_object_hierarchy, GTK_TYPE_BOX)
46 
47 static void
48 gtk_inspector_object_hierarchy_init (GtkInspectorObjectHierarchy *oh)
49 {
50   oh->priv = gtk_inspector_object_hierarchy_get_instance_private (oh);
51   gtk_widget_init_template (GTK_WIDGET (oh));
52 }
53 
54 static void
gtk_inspector_object_hierarchy_class_init(GtkInspectorObjectHierarchyClass * klass)55 gtk_inspector_object_hierarchy_class_init (GtkInspectorObjectHierarchyClass *klass)
56 {
57   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
58 
59   gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/object-hierarchy.ui");
60   gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorObjectHierarchy, model);
61   gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorObjectHierarchy, tree);
62 }
63 
64 void
gtk_inspector_object_hierarchy_set_object(GtkInspectorObjectHierarchy * oh,GObject * object)65 gtk_inspector_object_hierarchy_set_object (GtkInspectorObjectHierarchy *oh,
66                                            GObject                     *object)
67 {
68   GType type;
69   const gchar *class_name;
70   GtkTreeIter iter, parent;
71   GList *list = NULL, *l;
72   GHashTable *interfaces;
73   GHashTableIter hit;
74   GType *ifaces;
75   gint i;
76 
77   gtk_tree_store_clear (oh->priv->model);
78 
79   if (object == NULL)
80     return;
81 
82   interfaces = g_hash_table_new (g_str_hash, g_str_equal);
83   type = ((GTypeInstance*)object)->g_class->g_type;
84 
85   do
86     {
87       class_name = g_type_name (type);
88       list = g_list_append (list, (gpointer)class_name);
89       ifaces = g_type_interfaces (type, NULL);
90       for (i = 0; ifaces[i]; i++)
91         g_hash_table_add (interfaces, (gchar *)g_type_name (ifaces[i]));
92       g_free (ifaces);
93     }
94   while ((type = g_type_parent (type)));
95 
96   if (g_hash_table_size (interfaces) > 0)
97     {
98       gtk_tree_store_append (oh->priv->model, &iter, NULL);
99       gtk_tree_store_set (oh->priv->model, &iter,
100                           COLUMN_OBJECT_NAME, "GInterface",
101                           -1);
102       parent = iter;
103     }
104   g_hash_table_iter_init (&hit, interfaces);
105   while (g_hash_table_iter_next (&hit, (gpointer *)&class_name, NULL))
106     {
107       gtk_tree_store_append (oh->priv->model, &iter, &parent);
108       gtk_tree_store_set (oh->priv->model, &iter,
109                           COLUMN_OBJECT_NAME, class_name,
110                           -1);
111     }
112   g_hash_table_unref (interfaces);
113 
114   list = g_list_reverse (list);
115   for (l = list; l; l = l->next)
116     {
117       gtk_tree_store_append (oh->priv->model, &iter, l == list ? NULL : &parent);
118       gtk_tree_store_set (oh->priv->model, &iter,
119                           COLUMN_OBJECT_NAME, l->data,
120                           -1);
121       parent = iter;
122     }
123 
124   g_list_free (list);
125 
126   gtk_tree_view_expand_all (oh->priv->tree);
127   gtk_tree_selection_select_iter (gtk_tree_view_get_selection (oh->priv->tree), &iter);
128 }
129 
130 // vim: set et sw=2 ts=2:
131