Appending to treestore - how to set selection on new entry?

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Appending to treestore - how to set selection on new entry?

David C. Rankin
All,

  I have been playing with an editor interface that has a treeview in the left
of an hpaned widget, and then instances of scrolled windows with textview
objects packed into a vbox in the right pane (to provide one or more splits
views of files to edit).

  When I add a new file (entry) to the treestore/treemodel, how do I adjust
the selection so that the new entry is selected? (or how do I get a treepath
or iter from the new entry to allow me to set the selection?) The treestore
holds the name of the entry in the 1st col and then a pointer to a struct
containing details for that textbuffer (e.g. line, col, full path, filemode,
uid/gid, textview and sourceview lang_id along with comment syntax, etc..)

  There are two instances when I need to set the treeview selection on a
specific entry:

 (1) when I append the entry to the tree, e.g.

    GtkTreeStore *treestore;
    GtkTreeIter toplevel;
    ...
    treestore = GTK_TREE_STORE(gtk_tree_view_get_model (
                                GTK_TREE_VIEW(app->treeview)));
    /* (validate omitted) */

    /* appeand name and pointer to inst as entry in treeview */
    gtk_tree_store_append (treestore, &toplevel, NULL);
    gtk_tree_store_set (treestore, &toplevel, COLNAME, name, -1);
    gtk_tree_store_set (treestore, &toplevel, COLINST, inst, -1);

    (here I know the 'inst' which is the pointer stored in column 2)

 (2) when the user clicks in one of the edit textviews (there can be multiple
split views) in right of the hpaned object. Currently I track which textview
is focused using the "focus-in-event" signal from the textview object to loop
over the array of editor instances to determine which textview widget is
focused (which also provides me with the 'inst' which is column 2 in the
treestore/model)

  So in both cases I have the value of the pointer that is stored in column 2
of the tree model.

  "How do I use the pointer stored in column 2 of the model to set the
selection on that treeview entry?"

(the full source of the interface is https://github.com/drankinatty/gtkate
which is just a concept at the moment, the project will provide the
functionality of https://github.com/drankinatty/gtkwrite within a
multi-document/multi-view interface when done)

  I have not worked with tree models/stores a great deal and I am a bit
bewildered by how to get an iter or treepath given the value of column 2 to
then set the selection on that row/entry in the treeview. I guess I could do a
for_each and loop over the pointers, but I'm unsure if that is the correct way
or one of my logical hacks that would be better implemented some other way.

  Any help greatly appreciated.

--
David C. Rankin, J.D.,P.E.
_______________________________________________
gtk-app-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: Appending to treestore - how to set selection on new entry?

David C. Rankin
On 08/27/2018 01:24 AM, David C. Rankin wrote:

>   "How do I use the pointer stored in column 2 of the model to set the
> selection on that treeview entry?"
>
> (the full source of the interface is https://github.com/drankinatty/gtkate
> which is just a concept at the moment, the project will provide the
> functionality of https://github.com/drankinatty/gtkwrite within a
> multi-document/multi-view interface when done)
>
>   I have not worked with tree models/stores a great deal and I am a bit
> bewildered by how to get an iter or treepath given the value of column 2 to
> then set the selection on that row/entry in the treeview. I guess I could do a
> for_each and loop over the pointers, but I'm unsure if that is the correct way
> or one of my logical hacks that would be better implemented some other way.
>

Well,

  I'm not sure this was the best way to go about it, but from the callback
from the "focus-in-event" signal from the textview, I call the following which
uses the pointer to the textview buffer to compare for equality against the
pointer held in each treemodel instance pointer. This gives me the GtkTreeIter
that I can then use with gtk_tree_selection_select_iter(), e.g.

/** given inst use tree iter to set focus on current view
 *  (widget is textview associated with window clicked inside)
 */
void tree_get_inst_iter (GtkWidget *widget, gpointer data)
{
    mainwin_t *app = data;
    GtkTreeModel *model = NULL;
    GtkTreeSelection *selection;
    GtkTreeIter iter;
    gpointer buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
    gboolean valid, found = FALSE;

    /* initialize selection to current */
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(app->treeview));

    /* get treemodel, validate */
    model = gtk_tree_view_get_model(GTK_TREE_VIEW(app->treeview));
    if (!model) {
        g_print ("error: tree_view_get_model - failed.\n");
        return;
    }

    /* get first iter, return in validate */
    valid = gtk_tree_model_get_iter_first (model, &iter);
    while (valid) {         /* loop over each entry in model */
        gchar *str = NULL;
        kinst_t *inst = NULL;

        /* TODO - remove COLNAME & str after debugging done */
        gtk_tree_model_get (model, &iter,   /* get name & inst */
                            COLNAME, &str, COLINST, &inst, -1);

        /* compare pointer to sourceview with buf from textview (widget) */
        if ((gpointer)(inst->buf) == buf) {
            gtk_tree_selection_select_iter (selection, &iter);
            g_free (str);
            found = TRUE;
            break;
        }
        g_free (str);

        valid = gtk_tree_model_iter_next (model, &iter);
    }

    if (!found)
        g_warning ("tree_get_inst_iter inst not found.");

    if (widget) {}
}


--
David C. Rankin, J.D.,P.E.
_______________________________________________
gtk-app-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: Appending to treestore - how to set selection on new entry?

Gtk+ - Apps Dev mailing list
In reply to this post by David C. Rankin
Op 27-08-18 om 08:24 schreef David C. Rankin:

>   When I add a new file (entry) to the treestore/treemodel, how do I adjust
> the selection so that the new entry is selected? (or how do I get a treepath
> or iter from the new entry to allow me to set the selection?) The treestore
> holds the name of the entry in the 1st col and then a pointer to a struct
> containing details for that textbuffer (e.g. line, col, full path, filemode,
> uid/gid, textview and sourceview lang_id along with comment syntax, etc..)
>  (1) when I append the entry to the tree, e.g.
>
>     GtkTreeStore *treestore;
>     GtkTreeIter toplevel;

toplevel is the treeiter you use to set the selection.

>     ...
>     treestore = GTK_TREE_STORE(gtk_tree_view_get_model (
>                                 GTK_TREE_VIEW(app->treeview)));
>     /* (validate omitted) */
>
>     /* appeand name and pointer to inst as entry in treeview */
>     gtk_tree_store_append (treestore, &toplevel, NULL);
>     gtk_tree_store_set (treestore, &toplevel, COLNAME, name, -1);
>     gtk_tree_store_set (treestore, &toplevel, COLINST, inst, -1);
>
>     (here I know the 'inst' which is the pointer stored in column 2)

Next is to get the selection from your view with
gtk_tree_view_get_selection and call gtk_tree_selection_select_iter with
the toplevel iter from earlier. It should now have selected the newly
added row.

~infirit
_______________________________________________
gtk-app-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: Appending to treestore - how to set selection on new entry?

David C. Rankin
On 08/28/2018 04:24 PM, infirit wrote:
> Next is to get the selection from your view with
> gtk_tree_view_get_selection and call gtk_tree_selection_select_iter with
> the toplevel iter from earlier. It should now have selected the newly
> added row.
>
> ~infirit

Yes, thank you, that is what I did. The problem I had to solve was the reverse
of the appending case. There where toplevel is used, I am simply adding an
entry to the tree model. The case I had to solve was when the model was
completely filled and I had multiple views which could be associated with any
one instance contained in the model. The challenge was to take the focus on
any of the views and then go figure out which entry in the tree model the
focused textview buffer came from.

For example, here is the editor interface shown with the treeview and 3 editor
windows:

http://paste.opensuse.org/25076757

The task was to be able to click to place focus in any one of the edit
(textview) windows and have the selection automatically move to the associated
file. That's where using the "focus-in-event" signal from the textview allowed
getting the associated buffer which I could then iterate through the treemodel
and match with the buffer held in the model using the iterator to set the
selection.


--
David C. Rankin, J.D.,P.E.
_______________________________________________
gtk-app-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list