I like option 2. Strange that I didn't think of it, as this exactly what I usually do for std::vector (although the performance of deleting from the middle of a vector is obviously not good)
David Nečas (Yeti) wrote: > On Fri, Jul 21, 2006 at 11:23:40PM +0100, Christopher Backhouse wrote: >> so - I loop through the selection, converting all the paths into >> references and put them in a new list. >> Then I loop through that list, convert the references back to iters so i >> can remove them from the tree. >> It also seems to be impossible to convert a reference to an iter - so I >> have to go via a path. >> All in all not the prettiest code, but at least it works. >> If there is a neater solution I would be happy to hear about it > > This method is quite general, but it has indeed a large > overhead. See the attached example for two simplier > methods. > > Yeti > > > -- > Anonyms eat their boogers. > > > ========================================================================== > #include <gtk/gtk.h> > > static void > add_iter(GtkTreeModel *model, > GtkTreePath *path, > GtkTreeIter *piter, > gpointer userdata) > { > GArray *sel = (GArray*)userdata; > GtkTreeIter iter = *piter; > > g_array_append_val(sel, iter); > } > > static void > remove1(GtkTreeSelection *selection) > { > GtkTreeView *treeview; > GtkListStore *store; > GArray *sel; > guint i; > > treeview = gtk_tree_selection_get_tree_view(selection); > store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview)); > > sel = g_array_new(FALSE, FALSE, sizeof(GtkTreeIter)); > /* This needs persistent iters */ > gtk_tree_selection_selected_foreach(selection, add_iter, sel); > gtk_tree_selection_unselect_all(selection); > for (i = 0; i < sel->len; i++) { > GtkTreeIter *iter = &g_array_index(sel, GtkTreeIter, i); > > gtk_list_store_remove(store, iter); > } > g_array_free(sel, TRUE); > } > > static void > remove2(GtkTreeSelection *selection) > { > GtkTreeModel *model; > GtkListStore *store; > GList *sel, *l; > > sel = gtk_tree_selection_get_selected_rows(selection, &model); > gtk_tree_selection_unselect_all(selection); > store = GTK_LIST_STORE(model); > /* This assumes paths are in order. Although it works there is no such > * guarantee in Gtk+ API docs, so maybe a sort is necessary. */ > sel = g_list_reverse(sel); > for (l = sel; l; l = g_list_next(l)) { > GtkTreeIter iter; > GtkTreePath *path = (GtkTreePath*)l->data; > > gtk_tree_model_get_iter(model, &iter, path); > gtk_list_store_remove(store, &iter); > gtk_tree_path_free(path); > } > g_list_free(sel); > } > > /* This is gross */ > static void > fill(GtkListStore *store) > { > GtkTreeIter iter; > guint i; > > gtk_list_store_clear(store); > > for (i = 0; i < 20; i++) { > gtk_list_store_append(store, &iter); > gtk_list_store_set(store, &iter, 0, i, -1); > } > } > > int > main(int argc, char *argv[]) > { > GtkWidget *window, *treeview, *vbox, *button; > GtkTreeViewColumn *column; > GtkCellRenderer *renderer; > GtkTreeSelection *selection; > GtkListStore *store; > > gtk_init(&argc, &argv); > > store = gtk_list_store_new(1, G_TYPE_UINT); > fill(store); > > window = gtk_window_new(GTK_WINDOW_TOPLEVEL); > g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); > > vbox = gtk_vbox_new(FALSE, 0); > gtk_container_add(GTK_CONTAINER(window), vbox); > > treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); > gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE); > > renderer = gtk_cell_renderer_text_new(); > column = gtk_tree_view_column_new(); > gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(column), renderer, TRUE); > gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(column), renderer, "text", > 0); > gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); > gtk_box_pack_start(GTK_BOX(vbox), treeview, TRUE, TRUE, 0); > > selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); > gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); > > button = gtk_button_new_from_stock(GTK_STOCK_REMOVE); > gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); > g_signal_connect_swapped(button, "clicked", G_CALLBACK(remove1), > selection); > > button = gtk_button_new_from_stock(GTK_STOCK_DELETE); > gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); > g_signal_connect_swapped(button, "clicked", G_CALLBACK(remove2), > selection); > > button = gtk_button_new_with_mnemonic("_Fill"); > gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); > g_signal_connect_swapped(button, "clicked", G_CALLBACK(fill), store); > > gtk_widget_show_all(window); > gtk_main(); > > return 0; > } > > _______________________________________________ > gtk-app-devel-list mailing list > gtk-app-devel-list@gnome.org > http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list > _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list