/* Tree View/Filter Model * #Keywords: GtkTreeView * * This example demonstrates how GtkTreeModelFilter can be used not * just to show a subset of the rows, but also to compute columns * that are not actually present in the underlying model. */ #include #include G_GNUC_BEGIN_IGNORE_DEPRECATIONS enum { WIDTH_COLUMN, HEIGHT_COLUMN, AREA_COLUMN, SQUARE_COLUMN }; static void format_number (GtkTreeViewColumn *col, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer data) { int num; char *text; gtk_tree_model_get (model, iter, GPOINTER_TO_INT (data), &num, -1); text = g_strdup_printf ("%d", num); g_object_set (cell, "text", text, NULL); g_free (text); } static void filter_modify_func (GtkTreeModel *model, GtkTreeIter *iter, GValue *value, int column, gpointer data) { GtkTreeModelFilter *filter_model = GTK_TREE_MODEL_FILTER (model); int width, height; GtkTreeModel *child_model; GtkTreeIter child_iter; child_model = gtk_tree_model_filter_get_model (filter_model); gtk_tree_model_filter_convert_iter_to_child_iter (filter_model, &child_iter, iter); gtk_tree_model_get (child_model, &child_iter, WIDTH_COLUMN, &width, HEIGHT_COLUMN, &height, -1); switch (column) { case WIDTH_COLUMN: g_value_set_int (value, width); break; case HEIGHT_COLUMN: g_value_set_int (value, height); break; case AREA_COLUMN: g_value_set_int (value, width * height); break; case SQUARE_COLUMN: g_value_set_boolean (value, width == height); break; default: g_assert_not_reached (); } } static gboolean visible_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data) { int width; gtk_tree_model_get (model, iter, WIDTH_COLUMN, &width, -1); return width < 10; } static void cell_edited (GtkCellRendererSpin *cell, const char *path_string, const char *new_text, GtkListStore *store) { int val; GtkTreePath *path; GtkTreeIter iter; int column; path = gtk_tree_path_new_from_string (path_string); gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path); gtk_tree_path_free (path); column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), "column")); val = atoi (new_text); gtk_list_store_set (store, &iter, column, val, -1); } GtkWidget * do_filtermodel (GtkWidget *do_widget) { static GtkWidget *window; GtkWidget *tree; GtkListStore *store; GtkTreeModel *model; GtkTreeViewColumn *column; GtkCellRenderer *cell; GType types[4]; if (!window) { GtkBuilder *builder; builder = gtk_builder_new_from_resource ("/filtermodel/filtermodel.ui"); window = GTK_WIDGET (gtk_builder_get_object (builder, "window1")); gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget)); g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window); store = (GtkListStore*)gtk_builder_get_object (builder, "liststore1"); column = (GtkTreeViewColumn*)gtk_builder_get_object (builder, "treeviewcolumn1"); cell = (GtkCellRenderer*)gtk_builder_get_object (builder, "cellrenderertext1"); gtk_tree_view_column_set_cell_data_func (column, cell, format_number, GINT_TO_POINTER (WIDTH_COLUMN), NULL); g_object_set_data (G_OBJECT (cell), "column", GINT_TO_POINTER (WIDTH_COLUMN)); g_signal_connect (cell, "edited", G_CALLBACK (cell_edited), store); column = (GtkTreeViewColumn*)gtk_builder_get_object (builder, "treeviewcolumn2"); cell = (GtkCellRenderer*)gtk_builder_get_object (builder, "cellrenderertext2"); gtk_tree_view_column_set_cell_data_func (column, cell, format_number, GINT_TO_POINTER (HEIGHT_COLUMN), NULL); g_object_set_data (G_OBJECT (cell), "column", GINT_TO_POINTER (HEIGHT_COLUMN)); g_signal_connect (cell, "edited", G_CALLBACK (cell_edited), store); column = (GtkTreeViewColumn*)gtk_builder_get_object (builder, "treeviewcolumn3"); cell = (GtkCellRenderer*)gtk_builder_get_object (builder, "cellrenderertext3"); gtk_tree_view_column_set_cell_data_func (column, cell, format_number, GINT_TO_POINTER (WIDTH_COLUMN), NULL); column = (GtkTreeViewColumn*)gtk_builder_get_object (builder, "treeviewcolumn4"); cell = (GtkCellRenderer*)gtk_builder_get_object (builder, "cellrenderertext4"); gtk_tree_view_column_set_cell_data_func (column, cell, format_number, GINT_TO_POINTER (HEIGHT_COLUMN), NULL); column = (GtkTreeViewColumn*)gtk_builder_get_object (builder, "treeviewcolumn5"); cell = (GtkCellRenderer*)gtk_builder_get_object (builder, "cellrenderertext5"); gtk_tree_view_column_set_cell_data_func (column, cell, format_number, GINT_TO_POINTER (AREA_COLUMN), NULL); column = (GtkTreeViewColumn*)gtk_builder_get_object (builder, "treeviewcolumn6"); cell = (GtkCellRenderer*)gtk_builder_get_object (builder, "cellrendererpixbuf1"); gtk_tree_view_column_add_attribute (column, cell, "visible", SQUARE_COLUMN); tree = (GtkWidget*)gtk_builder_get_object (builder, "treeview2"); types[WIDTH_COLUMN] = G_TYPE_INT; types[HEIGHT_COLUMN] = G_TYPE_INT; types[AREA_COLUMN] = G_TYPE_INT; types[SQUARE_COLUMN] = G_TYPE_BOOLEAN; model = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL); gtk_tree_model_filter_set_modify_func (GTK_TREE_MODEL_FILTER (model), G_N_ELEMENTS (types), types, filter_modify_func, NULL, NULL); gtk_tree_view_set_model (GTK_TREE_VIEW (tree), model); column = (GtkTreeViewColumn*)gtk_builder_get_object (builder, "treeviewcolumn7"); cell = (GtkCellRenderer*)gtk_builder_get_object (builder, "cellrenderertext6"); gtk_tree_view_column_set_cell_data_func (column, cell, format_number, GINT_TO_POINTER (WIDTH_COLUMN), NULL); column = (GtkTreeViewColumn*)gtk_builder_get_object (builder, "treeviewcolumn8"); cell = (GtkCellRenderer*)gtk_builder_get_object (builder, "cellrenderertext7"); gtk_tree_view_column_set_cell_data_func (column, cell, format_number, GINT_TO_POINTER (HEIGHT_COLUMN), NULL); tree = (GtkWidget*)gtk_builder_get_object (builder, "treeview3"); model = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL); gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (model), visible_func, NULL, NULL); gtk_tree_view_set_model (GTK_TREE_VIEW (tree), model); g_object_unref (builder); } if (!gtk_widget_get_visible (window)) gtk_widget_show (window); else gtk_window_destroy (GTK_WINDOW (window)); return window; }