BUG: gtk_list_store_remove() causes GtkTreeView cursor to disappear



This is more or less the same issue I raised with the GtkCList widget.
A little different though.

When I move the cursor on a GtkTreeView to an item and then delete it
(with say a button, like in the editable-cells gtk demo), the cursor
(the highligted bar) disappears.  I have to either click on the list
(if I even have a mouse!) to get a new one or move the cursor down
with an arrow key, at which point I am at the top of the list again.

This is ugly.  It is not at all intuitive.  I would call it a bug.  If
I have an item highlighted and I delete it, I expect the cursor to
remain in the viciinity of the deleted item, either before it or after
it.

Think about a list with 10,000 items in it and you use the cursor down
(because you have no mouse) to scroll down 6000 or so items and want
to delete a few items in the same area.  You wind up moving the cursor
from the top of the list down 6000 items every single time rather than
a delete and a move of a few items and a delete and a move of a few
more, etc.

I have been able to mostly work around this by hooking a callback to
the row-deleted signal of the GtkTreeModel, but I find I am writing
code that the widget should handle itself.  I have to block the
callback during a gtk_list_store_clear() and restore it afterward.
It's all just mucky stuff that the widget should deal with internally.

Anyway, here is my callback so far:

void
row_deleted(GtkTreeModel *treemodel,
            GtkTreePath *arg1,
            gpointer user_data)
{

  GtkTreeView *tree_view = program_list;
  GtkTreePath *path;

  gtk_tree_view_get_cursor(tree_view, &path, NULL);

  // if the row being deleted is the row the cursor is on...
  if (!gtk_tree_path_compare(arg1, path)) {
    GtkTreeIter iter;
    gtk_tree_model_get_iter(treemodel, &iter, path);
    if (!gtk_tree_model_iter_next(treemodel, &iter))
      // last row is selected and being deleted, move to prev row
      gtk_tree_path_prev(path);
    else 
#if 0
      // get the path from the updated iter
      path = gtk_tree_model_get_path(treemodel, &iter);
#else
      // just bump the path using path_next
      gtk_tree_path_next(path);
#endif
    gtk_tree_view_set_cursor(tree_view, path, NULL, FALSE);

  }

}

But this doesn't exactly work.  It gives me the following errors on
stderr:

(chooser2:9418): Gtk-CRITICAL **: file gtkliststore.c: line 571 (gtk_list_store_iter_next): assertion `GTK_LIST_STORE (tree_model)->stamp == iter->stamp' failed

(chooser2:9418): Gtk-CRITICAL **: file gtktreeview.c: line 3073 (gtk_tree_view_bin_expose): assertion `has_next' failed.
There is a disparity between the internal view of the GtkTreeView,
and the GtkTreeModel.  This generally means that the model has changed
without letting the view know.  Any display from now on is likely to
be incorrect.

So something I am doing is obviously wrong.  This only happens in the
case where gtk_tree_model_iter_next(treemodel, &iter) returns FALSE
(i.e. the cursor is on the last item in the list and it is being
deleted).  I am not sure what though.  It sure would be nice if there
were a gtk_tree_model_iter_prev().  I suspect that the only way I am
going to get this to work is to walk from
gtk_tree_model_get_iter_first() to gtk_tree_model_get_iter() and
remember the previous iter to simulate a gtk_tree_model_iter_prev().

Comments?

b.

-- 
Brian J. Murrell

Attachment: pgp608megaR84.pgp
Description: PGP signature



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