/** @brief helper function to recursively copy a treestore @param srcmodel treemodel for store being copied @param srcparent pointer to source treeiter which has been confirmed to have child(ren) @param deststore the store to which data is being copied @param destparent pointer to destination store treeiter @param ncols no. of columns in @a model @param colnums array of column indices @param types array of GTypes corresponding to columns @param values array in which to store values being transferred @return */ static void _e2_tree_copy_descendants ( GtkTreeModel *srcmodel, GtkTreeIter *srcparent, GtkTreeStore *deststore, GtkTreeIter *destparent, gint ncols, gint colnums[], GType types[], GValue values[]) { GtkTreeIter child; if (gtk_tree_model_iter_children (srcmodel, &child, srcparent)) { gint i; GtkTreeIter dest; do { //read iter into pointers array for (i = 0; i < ncols; i++) gtk_tree_model_get_value (srcmodel, &child, i, &values[i]); #ifdef USE_GTK2_10 gtk_tree_store_insert_with_valuesv (deststore, &dest, destparent, -1, colnums, values, ncols); for (i = 0; i < ncols; i++) g_value_unset (&values[i]); #else gtk_tree_store_append (deststore, &dest, destparent); for (i = 0; i < ncols; i++) { gtk_tree_store_set_value (deststore, &dest, i, &values[i]); g_value_unset (&values[i]); } #endif if (gtk_tree_model_iter_has_child (srcmodel, &child)) _e2_tree_copy_descendants (srcmodel, &child, deststore, &dest, ncols, colnums, types, values); } while (gtk_tree_model_iter_next (srcmodel, &child)); } }
static VALUE rg_insert(int argc, VALUE *argv, VALUE self) { VALUE parent, position, values, ret; GtkTreeIter iter; GtkTreeStore* model = _SELF(self); rb_scan_args(argc, argv, "21", &parent, &position, &values); if (NIL_P(values)){ gtk_tree_store_insert(model, &iter, NIL_P(parent) ? NULL : RVAL2GTKTREEITER(parent), NUM2INT(position)); iter.user_data3 = model; ret = GTKTREEITER2RVAL(&iter); G_CHILD_ADD(self, ret); } else { #if GTK_CHECK_VERSION(2,10,0) gint *c_columns; GValue *c_values; long size, i; size = NUM2INT(rb_funcall(values, rb_intern("size"), 0)); c_columns = ALLOCA_N(gint, size); c_values = ALLOCA_N(GValue, size); if(TYPE(values)==T_ARRAY) { for(i=0; i<size; i++) { GType gtype; GValue gval = G_VALUE_INIT; c_columns[i] = i; gtype = gtk_tree_model_get_column_type(GTK_TREE_MODEL(RVAL2GOBJ(self)), c_columns[i]); g_value_init(&gval, gtype); rbgobj_rvalue_to_gvalue(rb_ary_shift(values), &gval); c_values[i] = gval; } } else if(TYPE(values)==T_HASH) { VALUE r_columns; r_columns = rb_funcall(values, rb_intern("keys"), 0); for(i=0; i<size; i++) { GType gtype; GValue gval = G_VALUE_INIT; c_columns[i] = NUM2INT (rb_ary_entry(r_columns, i)); gtype = gtk_tree_model_get_column_type(GTK_TREE_MODEL(RVAL2GOBJ(self)), c_columns[i]); g_value_init(&gval, gtype); rbgobj_rvalue_to_gvalue(rb_hash_aref(values, INT2NUM(c_columns[i])), &gval); c_values[i] = gval; } } else { rb_raise(rb_eArgError, "values must be of type Hash or Array"); } gtk_tree_store_insert_with_valuesv(model, &iter, NIL_P(parent) ? NULL : RVAL2GTKTREEITER(parent), NUM2INT(position), c_columns, c_values, size); iter.user_data3 = model; ret = GTKTREEITER2RVAL(&iter); G_CHILD_ADD(self, ret); for(i=0; i<size; i++) { G_CHILD_ADD(ret, rbgobj_gvalue_to_rvalue(&(c_values[i]))); g_value_unset(&(c_values[i])); } #else rb_warn("Gtk::TreeStore#insert(parent, position, values) requires GTK+-2.10.0 or later"); gtk_tree_store_insert(model, &iter, NIL_P(parent) ? NULL : RVAL2GTKTREEITER(parent), NUM2INT(position)); iter.user_data3 = model; ret = GTKTREEITER2RVAL(&iter); G_CHILD_ADD(self, ret); #endif } return ret; }