7.2. GtkTreeModelSort

GtkTreeModelSort is a wrapper tree model. It takes another tree model such as a list store or a tree store as child model, and presents the child model to the 'outside' (ie. a tree view or whoever else is accessing it via the tree model interface) in a sorted state. It does that without changing the order of the rows in the child model. This is useful if you want to display the same model in different tree views with different sorting criteria for each tree view, for example, or if you need to restore the original unsorted state of your store again at some point.

GtkTreeModelSort implements the GtkTreeSortable interface, so you can treat it just as if it was your data store for sorting purposes. Here is the basic setup with a tree view:


  ...

  void
  create_list_and_view (void)
  {
    ...

    liststore = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_UINT);

    sortmodel = gtk_tree_model_sort_new_with_model(liststore);

    gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(sortmodel), SORTID_NAME,
                                    sort_func, GINT_TO_POINTER(SORTID_NAME), NULL);

    gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(sortmodel), SORTID_YEAR,
                                    sort_func, GINT_TO_POINTER(SORTID_YEAR), NULL);

    /* set initial sort order */
    gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(sortmodel),
                                         SORTID_NAME, GTK_SORT_ASCENDING);

    ...

    view = gtk_tree_view_new_with_model(sortmodel);

    ...

  }

  ...

However, when using the sort tree model, you need to be careful when you use iters and paths with the model. This is because a path pointing to a row in the view (and the sort tree model here) does probably not point to the same row in the child model which is your original list store or tree store, because the row order in the child model is probably different from the sorted order. Similarly, an iter that is valid for the sort tree model is not valid for the child model, and vice versa. You can convert paths and iters from and to the child model using gtk_tree_model_sort_convert_child_path_to_path, gtk_tree_model_sort_convert_child_iter_to_iter, gtk_tree_model_sort_convert_path_to_child_path, and gtk_tree_model_sort_convert_iter_to_child_iter. You are unlikely to need these functions frequently though, as you can still directly use gtk_tree_model_get on the sort tree model with a path supplied by the tree view.

For the tree view, the sort tree model is the 'real' model - it knows nothing about the sort tree model's child model at all, which means that any path or iter that you get passed from the tree view in a callback or otherwise will refer to the sort tree model, and that you need to pass a path or iter refering to the sort tree model as well if you call tree view functions.