1/* Tree View/Filter Model
2 * #Keywords: GtkTreeView
3 *
4 * This example demonstrates how GtkTreeModelFilter can be used not
5 * just to show a subset of the rows, but also to compute columns
6 * that are not actually present in the underlying model.
7 */
8
9#include <gtk/gtk.h>
10#include <stdlib.h>
11
12enum {
13 WIDTH_COLUMN,
14 HEIGHT_COLUMN,
15 AREA_COLUMN,
16 SQUARE_COLUMN
17};
18
19static void
20format_number (GtkTreeViewColumn *col,
21 GtkCellRenderer *cell,
22 GtkTreeModel *model,
23 GtkTreeIter *iter,
24 gpointer data)
25{
26 int num;
27 char *text;
28
29 gtk_tree_model_get (tree_model: model, iter, GPOINTER_TO_INT (data), &num, -1);
30 text = g_strdup_printf (format: "%d", num);
31 g_object_set (object: cell, first_property_name: "text", text, NULL);
32 g_free (mem: text);
33}
34
35static void
36filter_modify_func (GtkTreeModel *model,
37 GtkTreeIter *iter,
38 GValue *value,
39 int column,
40 gpointer data)
41{
42 GtkTreeModelFilter *filter_model = GTK_TREE_MODEL_FILTER (model);
43 int width, height;
44 GtkTreeModel *child_model;
45 GtkTreeIter child_iter;
46
47 child_model = gtk_tree_model_filter_get_model (filter: filter_model);
48 gtk_tree_model_filter_convert_iter_to_child_iter (filter: filter_model, child_iter: &child_iter, filter_iter: iter);
49
50 gtk_tree_model_get (tree_model: child_model, iter: &child_iter,
51 WIDTH_COLUMN, &width,
52 HEIGHT_COLUMN, &height,
53 -1);
54
55 switch (column)
56 {
57 case WIDTH_COLUMN:
58 g_value_set_int (value, v_int: width);
59 break;
60 case HEIGHT_COLUMN:
61 g_value_set_int (value, v_int: height);
62 break;
63 case AREA_COLUMN:
64 g_value_set_int (value, v_int: width * height);
65 break;
66 case SQUARE_COLUMN:
67 g_value_set_boolean (value, v_boolean: width == height);
68 break;
69 default:
70 g_assert_not_reached ();
71 }
72}
73
74static gboolean
75visible_func (GtkTreeModel *model,
76 GtkTreeIter *iter,
77 gpointer data)
78{
79 int width;
80
81 gtk_tree_model_get (tree_model: model, iter,
82 WIDTH_COLUMN, &width,
83 -1);
84
85 return width < 10;
86}
87
88static void
89cell_edited (GtkCellRendererSpin *cell,
90 const char *path_string,
91 const char *new_text,
92 GtkListStore *store)
93{
94 int val;
95 GtkTreePath *path;
96 GtkTreeIter iter;
97 int column;
98
99 path = gtk_tree_path_new_from_string (path: path_string);
100 gtk_tree_model_get_iter (GTK_TREE_MODEL (store), iter: &iter, path);
101 gtk_tree_path_free (path);
102
103 column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), "column"));
104
105 val = atoi (nptr: new_text);
106
107 gtk_list_store_set (list_store: store, iter: &iter, column, val, -1);
108}
109
110GtkWidget *
111do_filtermodel (GtkWidget *do_widget)
112{
113 static GtkWidget *window;
114 GtkWidget *tree;
115 GtkListStore *store;
116 GtkTreeModel *model;
117 GtkTreeViewColumn *column;
118 GtkCellRenderer *cell;
119 GType types[4];
120
121 if (!window)
122 {
123 GtkBuilder *builder;
124
125 builder = gtk_builder_new_from_resource (resource_path: "/filtermodel/filtermodel.ui");
126 window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
127 gtk_window_set_display (GTK_WINDOW (window),
128 display: gtk_widget_get_display (widget: do_widget));
129 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
130
131 store = (GtkListStore*)gtk_builder_get_object (builder, name: "liststore1");
132
133 column = (GtkTreeViewColumn*)gtk_builder_get_object (builder, name: "treeviewcolumn1");
134 cell = (GtkCellRenderer*)gtk_builder_get_object (builder, name: "cellrenderertext1");
135 gtk_tree_view_column_set_cell_data_func (tree_column: column, cell_renderer: cell,
136 func: format_number, GINT_TO_POINTER (WIDTH_COLUMN), NULL);
137 g_object_set_data (G_OBJECT (cell), key: "column", GINT_TO_POINTER (WIDTH_COLUMN));
138 g_signal_connect (cell, "edited", G_CALLBACK (cell_edited), store);
139
140 column = (GtkTreeViewColumn*)gtk_builder_get_object (builder, name: "treeviewcolumn2");
141 cell = (GtkCellRenderer*)gtk_builder_get_object (builder, name: "cellrenderertext2");
142 gtk_tree_view_column_set_cell_data_func (tree_column: column, cell_renderer: cell,
143 func: format_number, GINT_TO_POINTER (HEIGHT_COLUMN), NULL);
144 g_object_set_data (G_OBJECT (cell), key: "column", GINT_TO_POINTER (HEIGHT_COLUMN));
145 g_signal_connect (cell, "edited", G_CALLBACK (cell_edited), store);
146
147 column = (GtkTreeViewColumn*)gtk_builder_get_object (builder, name: "treeviewcolumn3");
148 cell = (GtkCellRenderer*)gtk_builder_get_object (builder, name: "cellrenderertext3");
149 gtk_tree_view_column_set_cell_data_func (tree_column: column, cell_renderer: cell,
150 func: format_number, GINT_TO_POINTER (WIDTH_COLUMN), NULL);
151
152 column = (GtkTreeViewColumn*)gtk_builder_get_object (builder, name: "treeviewcolumn4");
153 cell = (GtkCellRenderer*)gtk_builder_get_object (builder, name: "cellrenderertext4");
154 gtk_tree_view_column_set_cell_data_func (tree_column: column, cell_renderer: cell,
155 func: format_number, GINT_TO_POINTER (HEIGHT_COLUMN), NULL);
156
157 column = (GtkTreeViewColumn*)gtk_builder_get_object (builder, name: "treeviewcolumn5");
158 cell = (GtkCellRenderer*)gtk_builder_get_object (builder, name: "cellrenderertext5");
159 gtk_tree_view_column_set_cell_data_func (tree_column: column, cell_renderer: cell,
160 func: format_number, GINT_TO_POINTER (AREA_COLUMN), NULL);
161
162 column = (GtkTreeViewColumn*)gtk_builder_get_object (builder, name: "treeviewcolumn6");
163 cell = (GtkCellRenderer*)gtk_builder_get_object (builder, name: "cellrendererpixbuf1");
164 gtk_tree_view_column_add_attribute (tree_column: column, cell_renderer: cell, attribute: "visible", column: SQUARE_COLUMN);
165
166 tree = (GtkWidget*)gtk_builder_get_object (builder, name: "treeview2");
167
168 types[WIDTH_COLUMN] = G_TYPE_INT;
169 types[HEIGHT_COLUMN] = G_TYPE_INT;
170 types[AREA_COLUMN] = G_TYPE_INT;
171 types[SQUARE_COLUMN] = G_TYPE_BOOLEAN;
172 model = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
173 gtk_tree_model_filter_set_modify_func (GTK_TREE_MODEL_FILTER (model),
174 G_N_ELEMENTS (types), types,
175 func: filter_modify_func, NULL, NULL);
176
177 gtk_tree_view_set_model (GTK_TREE_VIEW (tree), model);
178
179 column = (GtkTreeViewColumn*)gtk_builder_get_object (builder, name: "treeviewcolumn7");
180 cell = (GtkCellRenderer*)gtk_builder_get_object (builder, name: "cellrenderertext6");
181 gtk_tree_view_column_set_cell_data_func (tree_column: column, cell_renderer: cell,
182 func: format_number, GINT_TO_POINTER (WIDTH_COLUMN), NULL);
183
184 column = (GtkTreeViewColumn*)gtk_builder_get_object (builder, name: "treeviewcolumn8");
185 cell = (GtkCellRenderer*)gtk_builder_get_object (builder, name: "cellrenderertext7");
186 gtk_tree_view_column_set_cell_data_func (tree_column: column, cell_renderer: cell,
187 func: format_number, GINT_TO_POINTER (HEIGHT_COLUMN), NULL);
188
189 tree = (GtkWidget*)gtk_builder_get_object (builder, name: "treeview3");
190
191 model = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
192 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (model),
193 func: visible_func, NULL, NULL);
194 gtk_tree_view_set_model (GTK_TREE_VIEW (tree), model);
195
196 g_object_unref (object: builder);
197 }
198
199 if (!gtk_widget_get_visible (widget: window))
200 gtk_widget_show (widget: window);
201 else
202 gtk_window_destroy (GTK_WINDOW (window));
203
204 return window;
205}
206

source code of gtk/demos/gtk-demo/filtermodel.c