Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get a GtkTreePath or GtkTreeIter to the last row in a GtkTreeModel?

Tags:

python

c

pygtk

gtk

I want to get a GtkTreePath or GtkTreeIter to the last row in a GtkTreeModel, but GtkTreeModel does not have a function for that.

I'll be happy with answers and examples in either C, or Python, or both ;).

like image 696
fresch Avatar asked May 24 '10 08:05

fresch


3 Answers

You should be able to go through a GtkTreePath, a bit of a hack maybe but still within the API:

GtkTreePath *path;
GtkTreeIter iter;

/* With NULL as iter, we get the number of toplevel nodes. */
gint rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(model), NULL);

/* Now get a path from the index. */
path = gtk_tree_path_new_from_indices(rows - 1, -1);

/* Ask the model for an iter to the node identified by the path. */
gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path);

/* Drop the path, we're done with it, iter is final output. */
gtk_tree_path_free(path);

Note: I haven't tested the above as I wrote it, but I'm pretty sure I've done something very similar in real code.

like image 113
unwind Avatar answered Oct 05 '22 06:10

unwind


Here is how I do it currently, but it seems clumsy...

C example:

void get_iter_last( GtkTreeModel *mdl, GtkTreeIter *itr )
{
  GtkTreeIter i;
  if ( gtk_tree_model_get_iter_first( mdl, &i ) ) {
    while ( gtk_tree_model_iter_next( mdl, &i ) ) {
      *itr = i;
    }
  }
}

Python example:

def get_iter_last( mdl ):
  itr = mdl.get_iter_first()
  last = None
  while itr:
    last = itr
    itr = mdl.iter_next( itr )
  return last
like image 32
fresch Avatar answered Oct 05 '22 06:10

fresch


Thanks for all previous answers, however I believe that final solution should include that TreeModel (with TreeStore) can store items with many levels of nesting (eg. path (2,0,4,2)). Solution posted by 'fresh' didn't worked for me, as I needed a function that will properly traverse thru all of the last children, until it really finds last row. Below is my final solution:

def get_last_iter (self, model):
    n = model.iter_n_children (None)
    # list empty
    if n == 0:
        return None
    else:
        iter = model.iter_nth_child (None, n - 1)
        n = model.iter_n_children (iter)
        # last top-level item has no children, so select that last item
        if n == 0:
            return iter
        else:
            # traverse thru every last child
            while 1:
                iter = model.iter_nth_child (iter, n - 1)
                n = model.iter_n_children (iter)
                if n == 0:
                    return iter

Or even shorter form:

def get_last_iter (self, model):
    iter = None
    n = 0
    while 1:
        iter = model.iter_nth_child (iter, n - 1)
        n = model.iter_n_children (iter)
        if n == 0:
            return iter
like image 28
HezniK Avatar answered Oct 05 '22 05:10

HezniK