1 | /* |
2 | * Copyright (c) 2014, 2020 Red Hat, Inc. |
3 | * |
4 | * This library is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2 of the License, or (at your option) any later version. |
8 | * |
9 | * This library is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Lesser General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Lesser General Public |
15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
16 | */ |
17 | |
18 | #include "config.h" |
19 | #include <glib/gi18n-lib.h> |
20 | |
21 | #include "tree-data.h" |
22 | |
23 | #include "object-tree.h" |
24 | |
25 | #include "gtktreeview.h" |
26 | #include "gtkcellrenderertext.h" |
27 | #include "gtktogglebutton.h" |
28 | #include "gtklabel.h" |
29 | #include "gtkstack.h" |
30 | #include "gtkboxlayout.h" |
31 | #include "gtkorientable.h" |
32 | |
33 | |
34 | struct _GtkInspectorTreeData |
35 | { |
36 | GtkWidget parent_instance; |
37 | |
38 | GtkTreeModel *object; |
39 | GtkTreeModel *types; |
40 | GtkTreeView *view; |
41 | GtkWidget *object_title; |
42 | gboolean show_data; |
43 | }; |
44 | |
45 | typedef struct _GtkInspectorTreeDataClass GtkInspectorTreeDataClass; |
46 | struct _GtkInspectorTreeDataClass |
47 | { |
48 | GtkWidgetClass parent_class; |
49 | }; |
50 | |
51 | |
52 | G_DEFINE_TYPE (GtkInspectorTreeData, gtk_inspector_tree_data, GTK_TYPE_WIDGET) |
53 | |
54 | static void |
55 | gtk_inspector_tree_data_init (GtkInspectorTreeData *sl) |
56 | { |
57 | gtk_widget_init_template (GTK_WIDGET (sl)); |
58 | |
59 | gtk_orientable_set_orientation (GTK_ORIENTABLE (gtk_widget_get_layout_manager (GTK_WIDGET (sl))), |
60 | orientation: GTK_ORIENTATION_VERTICAL); |
61 | } |
62 | |
63 | static void |
64 | cell_data_func (GtkTreeViewColumn *col, |
65 | GtkCellRenderer *cell, |
66 | GtkTreeModel *model, |
67 | GtkTreeIter *iter, |
68 | gpointer data) |
69 | { |
70 | int num; |
71 | GValue gvalue = { 0, }; |
72 | char *value; |
73 | |
74 | num = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (col), "num" )); |
75 | gtk_tree_model_get_value (tree_model: model, iter, column: num, value: &gvalue); |
76 | value = g_strdup_value_contents (value: &gvalue); |
77 | g_object_set (object: cell, first_property_name: "text" , value ? value : "" , NULL); |
78 | g_free (mem: value); |
79 | g_value_unset (value: &gvalue); |
80 | } |
81 | |
82 | static void |
83 | add_columns (GtkInspectorTreeData *sl) |
84 | { |
85 | int n_columns; |
86 | GtkCellRenderer *cell; |
87 | GType type; |
88 | char *title; |
89 | GtkTreeViewColumn *col; |
90 | int i; |
91 | |
92 | n_columns = gtk_tree_model_get_n_columns (tree_model: sl->object); |
93 | for (i = 0; i < n_columns; i++) |
94 | { |
95 | cell = gtk_cell_renderer_text_new (); |
96 | type = gtk_tree_model_get_column_type (tree_model: sl->object, index_: i); |
97 | title = g_strdup_printf (format: "%d: %s" , i, g_type_name (type)); |
98 | col = gtk_tree_view_column_new_with_attributes (title, cell, NULL); |
99 | g_object_set_data (G_OBJECT (col), key: "num" , GINT_TO_POINTER (i)); |
100 | gtk_tree_view_column_set_cell_data_func (tree_column: col, cell_renderer: cell, func: cell_data_func, func_data: sl, NULL); |
101 | gtk_tree_view_append_column (tree_view: sl->view, column: col); |
102 | g_free (mem: title); |
103 | } |
104 | } |
105 | |
106 | static void |
107 | show_types (GtkInspectorTreeData *sl) |
108 | { |
109 | gtk_tree_view_set_model (tree_view: sl->view, NULL); |
110 | sl->show_data = FALSE; |
111 | } |
112 | |
113 | static void |
114 | show_data (GtkInspectorTreeData *sl) |
115 | { |
116 | gtk_tree_view_set_model (tree_view: sl->view, model: sl->object); |
117 | sl->show_data = TRUE; |
118 | } |
119 | |
120 | static void |
121 | clear_view (GtkInspectorTreeData *sl) |
122 | { |
123 | gtk_tree_view_set_model (tree_view: sl->view, NULL); |
124 | while (gtk_tree_view_get_n_columns (tree_view: sl->view) > 0) |
125 | gtk_tree_view_remove_column (tree_view: sl->view, |
126 | column: gtk_tree_view_get_column (tree_view: sl->view, n: 0)); |
127 | } |
128 | |
129 | void |
130 | gtk_inspector_tree_data_set_object (GtkInspectorTreeData *sl, |
131 | GObject *object) |
132 | { |
133 | GtkWidget *stack; |
134 | GtkStackPage *page; |
135 | char *title; |
136 | |
137 | stack = gtk_widget_get_parent (GTK_WIDGET (sl)); |
138 | page = gtk_stack_get_page (GTK_STACK (stack), GTK_WIDGET (sl)); |
139 | |
140 | clear_view (sl); |
141 | sl->object = NULL; |
142 | sl->show_data = FALSE; |
143 | |
144 | if (!GTK_IS_TREE_MODEL (object)) |
145 | { |
146 | g_object_set (object: page, first_property_name: "visible" , FALSE, NULL); |
147 | return; |
148 | } |
149 | |
150 | title = gtk_inspector_get_object_title (object); |
151 | gtk_label_set_label (GTK_LABEL (sl->object_title), str: title); |
152 | g_free (mem: title); |
153 | |
154 | g_object_set (object: page, first_property_name: "visible" , TRUE, NULL); |
155 | |
156 | sl->object = GTK_TREE_MODEL (object); |
157 | add_columns (sl); |
158 | show_types (sl); |
159 | } |
160 | |
161 | static void |
162 | toggle_show (GtkToggleButton *button, |
163 | GtkInspectorTreeData *sl) |
164 | { |
165 | if (gtk_toggle_button_get_active (toggle_button: button) == sl->show_data) |
166 | return; |
167 | |
168 | if (gtk_toggle_button_get_active (toggle_button: button)) |
169 | show_data (sl); |
170 | else |
171 | show_types (sl); |
172 | } |
173 | |
174 | static void |
175 | dispose (GObject *object) |
176 | { |
177 | GtkInspectorTreeData *sl = GTK_INSPECTOR_TREE_DATA (object); |
178 | GtkWidget *child; |
179 | |
180 | while ((child = gtk_widget_get_first_child (GTK_WIDGET (sl)))) |
181 | gtk_widget_unparent (widget: child); |
182 | |
183 | G_OBJECT_CLASS (gtk_inspector_tree_data_parent_class)->dispose (object); |
184 | } |
185 | |
186 | static void |
187 | gtk_inspector_tree_data_class_init (GtkInspectorTreeDataClass *klass) |
188 | { |
189 | GObjectClass *object_class = G_OBJECT_CLASS (klass); |
190 | GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); |
191 | |
192 | object_class->dispose = dispose; |
193 | |
194 | gtk_widget_class_set_template_from_resource (widget_class, resource_name: "/org/gtk/libgtk/inspector/tree-data.ui" ); |
195 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorTreeData, view); |
196 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorTreeData, object_title); |
197 | gtk_widget_class_bind_template_callback (widget_class, toggle_show); |
198 | |
199 | gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT); |
200 | } |
201 | |
202 | // vim: set et sw=2 ts=2: |
203 | |