Imagine one has a Gtk::ListStore and want to copy it’s content to another one with the same model. How do we do it.
The natural instinct would be to do something like,
void Copy(const Glib::RefPtr <Gtk::ListStore> &refFrom,
const Glib::RefPtr <Gtk::ListStore> &refTo)
{
for(auto iFrom: refFrom->children())
{
auto iTo = refTo->append();
auto oTo = *iTo;
oTo = *iFrom;
}
}
This is the closest to a compilable code that we can get but doesn’t do the job. At the end of the call we will have some blank rows in the target store.
The following one works but is mostly C (not that I have anything against C).
void Copy(const Glib::RefPtr <Gtk::ListStore> &refFrom,
const Glib::RefPtr <Gtk::ListStore> &refTo)
{
auto pFrom = GTK_TREE_MODEL(refFrom->gobj());
auto pTo = refTo->gobj();
for (auto iFrom : refFrom->children())
{
auto iTo = refTo->append();
int n_columns = refFrom->get_n_columns();
for (int i = 0; i
< n_columns; ++i)
{
GValue value = G_VALUE_INIT
;
gtk_tree_model_get_value(pFrom,
const_cast <GtkTreeIter*>(iFrom->gobj()),
i,
&value);
gtk_list_store_set_value(pTo,
const_cast <GtkTreeIter*>(iTo->gobj()),
i,
&value);
g_value_unset(&value);
}
}
}
Is there a pure C++ way to do this?
A little bit about why I am doing this circus. I have a worker thread that loads data from a database. Since the Gtk::ListStore might have already been connected to a view, I can’t load the data directly into it from a non-ui thread. The thread creates a private store, loads data into it and hands it over to the main context using Glib::Dispatcher and that is where copying comes in.