Reputation: 1
I want to move some selected items between trees in Gtk+3 with Vala. The problem is that I cannot create a list to include all the item iterations that have to be removed, after adding them to the second tree (if I remove them just after adding them, only half of the selected items are correctly removed). It seems that Gtk.TreeIter is not a type, so I cannot make a list from it. If you need the complete code, I can happily publish it (just 109 lines of code), it's floss. Thank you.
valac --pkg gtk+-3.0 --pkg gee-0.8 treeview-prueba.vala
treeview-prueba.vala:75.23-75.34: error: `Gtk.TreeIter' is not a supported generic type argument, use `?' to box value types
75 | GLib.List<Gtk.TreeIter> iter_list_to_remove;
| ^~~~~~~~~~~~
treeview-prueba.vala:87.17-87.39: error: The name `add' does not exist in the context of `GLib.List<Gtk.TreeIter>?' (glib-2.0)
87 | iter_list_to_remove.add(itera2);
| ^~~~~~~~~~~~~~~~~~~~~~~
Compilation failed: 2 error(s), 0 warning(s)
make: *** [makefile:2: all] Error 1
The relevant code is:
delete_button.clicked.connect (() => {
var selection = view.get_selection ();
Value s= Value (typeof (string));
Gtk.TreeModel model;
Gtk.TreeIter itera;
Gtk.TreeIter itera2;
var selected_rows = selection.get_selected_rows(out model).data;
GLib.List<Gtk.TreeIter> iter_list_to_remove;
for (int i = 0; i<selection.count_selected_rows() ; i++) {
s="hola";
list_store.get_iter(out itera,selected_rows);
while (!selection.iter_is_selected (itera) ) {
list_store.get_iter(out itera,selected_rows);
selected_rows.next();
}
list_store.get_value(itera,0,out s);
stdout.printf( " %s ",s.get_string());
list_store2.append (out itera2);
list_store2.set (itera2,0,s.get_string());
iter_list_to_remove.add(itera2);
selected_rows.next();
}
foreach (var iteration in iter_list_to_remove){
list_store.remove(ref iteration);
}
});
I expected that it compiled correctly, but I get the above error.
Upvotes: 0
Views: 23
Reputation: 17522
Change GLib.List<Gtk.TreeIter>
to GLib.List<Gtk.TreeIter>
.
This is really a consequence of how generics are implemented in Vala, which reflects how these APIs are implemented in C. If you're not familiar with C (or a similar language) this may be a bit difficult to follow, sorry! Basically, at the C level the API for a "generic" function is implemented using an argument of type gpointer
, which is just a typedef to void*
. In other words, whatever value you pass there must fit inside of a pointer.
GtkTreeIter
(the C type) is typically passed as a value, not a reference, so for APIs like this what you really need to do is pass a pointer (i.e., a GtkTreeIter*
instead of a GtkTreeIter
). The best way to get Vala to do that is to mark it as nullable (GtkTreeIter?
). Technically you could also use a pointer in Vala, but to be perfectly honest you should almost never use pointers in Vala; you're basically opting out of memory management. Making it nullable makes Vala pass the argument as a pointer at the C level, but Vala will still handle the memory management for you.
Upvotes: 0