Re: Removing selected items from a list



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




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]