1 /* Tree View/Editable Cells
3 * This demo demonstrates the use of editable cells in a GtkTreeView. If
4 * you're new to the GtkTreeView widgets and associates, look into
5 * the GtkListStore example first.
7 * The cell renderers used in this demo are GtkCellRendererText and
8 * GtkCellRendererCombo.
15 static GtkWidget *window = NULL;
37 static GArray *articles = NULL;
44 g_return_if_fail (articles != NULL);
47 foo.product = g_strdup ("bottles of coke");
48 g_array_append_vals (articles, &foo, 1);
51 foo.product = g_strdup ("packages of noodles");
52 g_array_append_vals (articles, &foo, 1);
55 foo.product = g_strdup ("packages of chocolate chip cookies");
56 g_array_append_vals (articles, &foo, 1);
59 foo.product = g_strdup ("can vanilla ice cream");
60 g_array_append_vals (articles, &foo, 1);
63 foo.product = g_strdup ("eggs");
64 g_array_append_vals (articles, &foo, 1);
68 create_items_model (void)
75 articles = g_array_sized_new (FALSE, FALSE, sizeof (Item), 1);
79 /* create list store */
80 model = gtk_list_store_new (NUM_ITEM_COLUMNS, G_TYPE_INT, G_TYPE_STRING,
84 for (i = 0; i < articles->len; i++)
86 gtk_list_store_append (model, &iter);
88 gtk_list_store_set (model, &iter,
90 g_array_index (articles, Item, i).number,
92 g_array_index (articles, Item, i).product,
96 return GTK_TREE_MODEL (model);
100 create_numbers_model (void)
108 /* create list store */
109 model = gtk_list_store_new (NUM_NUMBER_COLUMNS, G_TYPE_STRING, G_TYPE_INT);
112 for (i = 0; i < N_NUMBERS; i++)
114 char str[2] = { '0' + i, '\0' };
116 gtk_list_store_append (model, &iter);
118 gtk_list_store_set (model, &iter,
119 COLUMN_NUMBER_TEXT, str,
123 return GTK_TREE_MODEL (model);
129 add_item (GtkWidget *button, gpointer data)
133 GtkTreeModel *model = (GtkTreeModel *)data;
135 g_return_if_fail (articles != NULL);
138 foo.product = g_strdup ("Description here");
139 g_array_append_vals (articles, &foo, 1);
141 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
142 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
143 COLUMN_ITEM_NUMBER, foo.number,
144 COLUMN_ITEM_PRODUCT, foo.product,
149 remove_item (GtkWidget *widget, gpointer data)
152 GtkTreeView *treeview = (GtkTreeView *)data;
153 GtkTreeModel *model = gtk_tree_view_get_model (treeview);
154 GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview);
156 if (gtk_tree_selection_get_selected (selection, NULL, &iter))
161 path = gtk_tree_model_get_path (model, &iter);
162 i = gtk_tree_path_get_indices (path)[0];
163 gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
165 g_array_remove_index (articles, i);
167 gtk_tree_path_free (path);
172 cell_edited (GtkCellRendererText *cell,
173 const gchar *path_string,
174 const gchar *new_text,
177 GtkTreeModel *model = (GtkTreeModel *)data;
178 GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
181 gint column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), "column"));
183 gtk_tree_model_get_iter (model, &iter, path);
187 case COLUMN_ITEM_NUMBER:
191 i = gtk_tree_path_get_indices (path)[0];
192 g_array_index (articles, Item, i).number = atoi (new_text);
194 gtk_list_store_set (GTK_LIST_STORE (model), &iter, column,
195 g_array_index (articles, Item, i).number, -1);
199 case COLUMN_ITEM_PRODUCT:
204 gtk_tree_model_get (model, &iter, column, &old_text, -1);
207 i = gtk_tree_path_get_indices (path)[0];
208 g_free (g_array_index (articles, Item, i).product);
209 g_array_index (articles, Item, i).product = g_strdup (new_text);
211 gtk_list_store_set (GTK_LIST_STORE (model), &iter, column,
212 g_array_index (articles, Item, i).product, -1);
217 gtk_tree_path_free (path);
221 add_columns (GtkTreeView *treeview,
222 GtkTreeModel *items_model,
223 GtkTreeModel *numbers_model)
225 GtkCellRenderer *renderer;
228 renderer = gtk_cell_renderer_combo_new ();
229 g_object_set (renderer,
230 "model", numbers_model,
231 "text-column", COLUMN_NUMBER_TEXT,
235 g_signal_connect (renderer, "edited",
236 G_CALLBACK (cell_edited), items_model);
237 g_object_set_data (G_OBJECT (renderer), "column", GINT_TO_POINTER (COLUMN_ITEM_NUMBER));
239 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
240 -1, "Number", renderer,
241 "text", COLUMN_ITEM_NUMBER,
245 renderer = gtk_cell_renderer_text_new ();
246 g_object_set (renderer,
249 g_signal_connect (renderer, "edited",
250 G_CALLBACK (cell_edited), items_model);
251 g_object_set_data (G_OBJECT (renderer), "column", GINT_TO_POINTER (COLUMN_ITEM_PRODUCT));
253 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
254 -1, "Product", renderer,
255 "text", COLUMN_ITEM_PRODUCT,
260 do_editable_cells (GtkWidget *do_widget)
269 GtkTreeModel *items_model;
270 GtkTreeModel *numbers_model;
272 /* create window, etc */
273 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
274 gtk_window_set_screen (GTK_WINDOW (window),
275 gtk_widget_get_screen (do_widget));
276 gtk_window_set_title (GTK_WINDOW (window), "Shopping list");
277 gtk_container_set_border_width (GTK_CONTAINER (window), 5);
278 g_signal_connect (window, "destroy",
279 G_CALLBACK (gtk_widget_destroyed), &window);
281 vbox = gtk_vbox_new (FALSE, 5);
282 gtk_container_add (GTK_CONTAINER (window), vbox);
284 gtk_box_pack_start (GTK_BOX (vbox),
285 gtk_label_new ("Shopping list (you can edit the cells!)"),
288 sw = gtk_scrolled_window_new (NULL, NULL);
289 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
290 GTK_SHADOW_ETCHED_IN);
291 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
292 GTK_POLICY_AUTOMATIC,
293 GTK_POLICY_AUTOMATIC);
294 gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
297 items_model = create_items_model ();
298 numbers_model = create_numbers_model ();
300 /* create tree view */
301 treeview = gtk_tree_view_new_with_model (items_model);
302 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
303 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
304 GTK_SELECTION_SINGLE);
306 add_columns (GTK_TREE_VIEW (treeview), items_model, numbers_model);
308 g_object_unref (numbers_model);
309 g_object_unref (items_model);
311 gtk_container_add (GTK_CONTAINER (sw), treeview);
314 hbox = gtk_hbox_new (TRUE, 4);
315 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
317 button = gtk_button_new_with_label ("Add item");
318 g_signal_connect (button, "clicked",
319 G_CALLBACK (add_item), items_model);
320 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
322 button = gtk_button_new_with_label ("Remove item");
323 g_signal_connect (button, "clicked",
324 G_CALLBACK (remove_item), treeview);
325 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
327 gtk_window_set_default_size (GTK_WINDOW (window), 320, 200);
330 if (!GTK_WIDGET_VISIBLE (window))
331 gtk_widget_show_all (window);
334 gtk_widget_destroy (window);