/*
* Copyright (c) 2003 by the gtk2-perl team (see the file AUTHORS)
*
* Licensed under the LGPL, see LICENSE file for more information.
*
* $Header: /cvsroot/gtk2-perl/gtk2-perl-xs/Gtk2/xs/GtkTreeModel.xs,v 1.37.2.1 2004/06/04 17:57:00 muppetman Exp $
*/
#include "gtk2perl.h"
#include <gperl_marshal.h>
/* this is just an interface */
static gboolean
gtk2perl_tree_model_foreach_func (GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer data)
{
GPerlCallback * callback = (GPerlCallback*)data;
GValue value = {0,};
gboolean retval;
g_value_init (&value, callback->return_type);
gperl_callback_invoke (callback, &value, model, path, iter);
retval = g_value_get_boolean (&value);
g_value_unset (&value);
return retval;
}
static void
gtk2perl_tree_model_rows_reordered_marshal (GClosure * closure,
GValue * return_value,
guint n_param_values,
const GValue * param_values,
gpointer invocation_hint,
gpointer marshal_data)
{
AV * av;
gint * new_order;
GtkTreeModel * model;
GtkTreeIter * iter;
int n_children, i;
dGPERL_CLOSURE_MARSHAL_ARGS;
GPERL_CLOSURE_MARSHAL_INIT (closure, marshal_data);
PERL_UNUSED_VAR (return_value);
PERL_UNUSED_VAR (n_param_values);
PERL_UNUSED_VAR (invocation_hint);
ENTER;
SAVETMPS;
PUSHMARK (SP);
/* instance */
GPERL_CLOSURE_MARSHAL_PUSH_INSTANCE (param_values);
model = SvGtkTreeModel(instance);
/* treepath */
XPUSHs (sv_2mortal (gperl_sv_from_value (param_values+1)));
/* treeiter */
XPUSHs (sv_2mortal (gperl_sv_from_value (param_values+2)));
iter = g_value_get_boxed (param_values+2);
/* gint * new_order */
new_order = g_value_get_pointer (param_values+3);
n_children = gtk_tree_model_iter_n_children (model, iter);
av = newAV ();
av_extend (av, n_children-1);
for (i = 0; i < n_children; i++)
av_store (av, i, newSViv (new_order[i]));
XPUSHs (sv_2mortal (newRV_noinc ((SV*)av)));
GPERL_CLOSURE_MARSHAL_PUSH_DATA;
PUTBACK;
GPERL_CLOSURE_MARSHAL_CALL (G_DISCARD);
/*
* clean up
*/
FREETMPS;
LEAVE;
}
/*
* GtkTreeModelIface
*/
/*
* Signals - these have class closures, so we can override them "normally"
* (for gtk2-perl, that is)
*
* row_changed
* row_inserted
* row_has_child_toggled
* row_deleted
* rows_reordered
*/
/*
* Virtual Table - things for which we must provide overrides
*/
static SV *
find_func (GtkTreeModel * tree_model,
const char * method_name)
{
HV * stash = gperl_object_stash_from_type (G_OBJECT_TYPE (tree_model));
return (SV*) gv_fetchmethod (stash, method_name);
}
#define PUSH_INSTANCE(var) \
PUSHs (sv_2mortal (newSVGObject (G_OBJECT (var))))
#define PREP(model) \
dSP; \
ENTER; \
SAVETMPS; \
PUSHMARK (SP); \
PUSHs (sv_2mortal (newSVGObject (G_OBJECT (model))));
#define CALL(name, flags) \
PUTBACK; \
call_method (name, flags); \
SPAGAIN;
#define FINISH \
PUTBACK; \
FREETMPS; \
LEAVE;
static GtkTreeModelFlags
gtk2perl_tree_model_get_flags (GtkTreeModel *tree_model)
{
GtkTreeModelFlags ret;
PREP (tree_model);
CALL ("GET_FLAGS", G_SCALAR);
ret = SvGtkTreeModelFlags (POPs);
FINISH;
return ret;
}
static gint
gtk2perl_tree_model_get_n_columns (GtkTreeModel *tree_model)
{
int ret;
PREP (tree_model);
CALL ("GET_N_COLUMNS", G_SCALAR);
ret = POPi;
FINISH;
return ret;
}
static GType
gtk2perl_tree_model_get_column_type (GtkTreeModel *tree_model,
gint index_)
{
GType ret;
SV * svret;
PREP (tree_model);
XPUSHs (sv_2mortal (newSViv (index_)));
CALL ("GET_COLUMN_TYPE", G_SCALAR);
svret = POPs;
PUTBACK;
ret = gperl_type_from_package (SvPV_nolen (svret));
if (!ret)
croak ("package %s is not registered with GPerl\n",
SvPV_nolen (svret));
FREETMPS;
LEAVE;
return ret;
}
static SV *
sv_from_iter (GtkTreeIter * iter)
{
AV * av = newAV ();
if (!iter)
return &PL_sv_undef;
av_push (av, newSVuv (iter->stamp));
av_push (av, newSViv (PTR2IV (iter->user_data)));
av_push (av, iter->user_data2 ? newRV (iter->user_data2) : &PL_sv_undef);
av_push (av, iter->user_data3 ? newRV (iter->user_data3) : &PL_sv_undef);
return newRV_noinc ((SV*)av);
}
static gboolean
iter_from_sv (GtkTreeIter * iter,
SV * sv)
{
if (sv && SvROK (sv) && SvTYPE (SvRV (sv)) == SVt_PVAV) {
SV ** svp;
AV * av = (AV*) SvRV (sv);
if ((svp = av_fetch (av, 0, FALSE)))
iter->stamp = SvUV (*svp);
if ((svp = av_fetch (av, 1, FALSE)) && SvIOK (*svp))
iter->user_data = INT2PTR (gpointer, SvIV (*svp));
else
iter->user_data = NULL;
if ((svp = av_fetch (av, 2, FALSE)) && SvROK (*svp))
iter->user_data2 = SvRV (*svp);
else
iter->user_data2 = NULL;
if ((svp = av_fetch (av, 3, FALSE)) && SvROK (*svp))
iter->user_data3 = SvRV (*svp);
else
iter->user_data3 = NULL;
return TRUE;
} else {
iter->stamp = 0;
iter->user_data = 0;
iter->user_data2 = 0;
iter->user_data3 = 0;
return FALSE;
}
}
static gboolean
gtk2perl_tree_model_get_iter (GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreePath *path)
{
gboolean ret;
PREP (tree_model);
XPUSHs (sv_2mortal (path ? newSVGtkTreePath (path) : &PL_sv_undef));
CALL ("GET_ITER", G_SCALAR);
ret = iter_from_sv (iter, POPs);
FINISH;
return ret;
}
static GtkTreePath *
gtk2perl_tree_model_get_path (GtkTreeModel *tree_model,
GtkTreeIter *iter)
{
GtkTreePath * ret = NULL;
SV * sv;
PREP (tree_model);
XPUSHs (sv_2mortal (sv_from_iter (iter)));
CALL ("GET_PATH", G_SCALAR);
sv = POPs;
/* restore the stack before parsing the output, since SvGtkTreePath
* might croak. FREETMPS will destroy the path, though, so we need
* to copy it, first. */
PUTBACK;
if (sv && SvOK (sv))
ret = gtk_tree_path_copy (SvGtkTreePath (sv));
FREETMPS;
LEAVE;
return ret;
}
static void
gtk2perl_tree_model_get_value (GtkTreeModel *tree_model,
GtkTreeIter *iter,
gint column,
GValue *value)
{
g_value_init (value,
gtk2perl_tree_model_get_column_type (tree_model, column));
{
PREP (tree_model);
XPUSHs (sv_2mortal (sv_from_iter (iter)));
XPUSHs (sv_2mortal (newSViv (column)));
CALL ("GET_VALUE", G_SCALAR);
gperl_value_from_sv (value, POPs);
FINISH;
}
}
static gboolean
gtk2perl_tree_model_iter_next (GtkTreeModel *tree_model,
GtkTreeIter *iter)
{
gboolean ret;
PREP (tree_model);
XPUSHs (sv_2mortal (sv_from_iter (iter)));
CALL ("ITER_NEXT", G_SCALAR);
ret = iter_from_sv (iter, POPs);
FINISH;
return ret;
}
static gboolean
gtk2perl_tree_model_iter_children (GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreeIter *parent)
{
gboolean ret;
PREP (tree_model);
XPUSHs (sv_2mortal (sv_from_iter (parent)));
CALL ("ITER_CHILDREN", G_SCALAR);
ret = iter_from_sv (iter, POPs);
FINISH;
return ret;
}
static gboolean
gtk2perl_tree_model_iter_has_child (GtkTreeModel *tree_model,
GtkTreeIter *iter)
{
gboolean ret;
PREP (tree_model);
XPUSHs (sv_2mortal (sv_from_iter (iter)));
CALL ("ITER_HAS_CHILD", G_SCALAR);
ret = POPi;
FINISH;
return ret;
}
static gint
gtk2perl_tree_model_iter_n_children (GtkTreeModel *tree_model,
GtkTreeIter *iter)
{
gint ret;
PREP (tree_model);
XPUSHs (sv_2mortal (sv_from_iter (iter)));
CALL ("ITER_N_CHILDREN", G_SCALAR);
ret = POPi;
FINISH;
return ret;
}
static gboolean
gtk2perl_tree_model_iter_nth_child (GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreeIter *parent,
gint n)
{
gboolean ret;
PREP (tree_model);
XPUSHs (sv_2mortal (sv_from_iter (parent)));
XPUSHs (sv_2mortal (newSViv (n)));
CALL ("ITER_NTH_CHILD", G_SCALAR);
ret = iter_from_sv (iter, POPs);
FINISH;
return ret;
}
static gboolean
gtk2perl_tree_model_iter_parent (GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreeIter *child)
{
gboolean ret;
PREP (tree_model);
XPUSHs (sv_2mortal (sv_from_iter (child)));
CALL ("ITER_PARENT", G_SCALAR);
ret = iter_from_sv (iter, POPs);
FINISH;
return ret;
}
static void
gtk2perl_tree_model_ref_node (GtkTreeModel *tree_model,
GtkTreeIter *iter)
{
SV * func = find_func (tree_model, "REF_NODE");
if (func) {
PREP (tree_model);
XPUSHs (sv_2mortal (sv_from_iter (iter)));
PUTBACK;
call_sv (func, G_VOID|G_DISCARD);
FINISH;
}
}
static void
gtk2perl_tree_model_unref_node (GtkTreeModel *tree_model,
GtkTreeIter *iter)
{
SV * func = find_func (tree_model, "UNREF_NODE");
if (func) {
PREP (tree_model);
XPUSHs (sv_2mortal (sv_from_iter (iter)));
PUTBACK;
call_sv (func, G_VOID|G_DISCARD);
FINISH;
}
}
static void
gtk2perl_tree_model_init (GtkTreeModelIface * iface)
{
iface->get_flags = gtk2perl_tree_model_get_flags;
iface->get_n_columns = gtk2perl_tree_model_get_n_columns;
iface->get_column_type = gtk2perl_tree_model_get_column_type;
iface->get_iter = gtk2perl_tree_model_get_iter;
iface->get_path = gtk2perl_tree_model_get_path;
iface->get_value = gtk2perl_tree_model_get_value;
iface->iter_next = gtk2perl_tree_model_iter_next;
iface->iter_children = gtk2perl_tree_model_iter_children;
iface->iter_has_child = gtk2perl_tree_model_iter_has_child;
iface->iter_n_children = gtk2perl_tree_model_iter_n_children;
iface->iter_nth_child = gtk2perl_tree_model_iter_nth_child;
iface->iter_parent = gtk2perl_tree_model_iter_parent;
iface->ref_node = gtk2perl_tree_model_ref_node;
iface->unref_node = gtk2perl_tree_model_unref_node;
}
MODULE = Gtk2::TreeModel PACKAGE = Gtk2::TreeModel
=for flags GtkTreeModelFlags
=cut
=for position DESCRIPTION
=head1 DESCRIPTION
The Gtk2::TreeModel provides a generic tree interface for use by the
Gtk2::TreeView widget. It is an abstract interface, designed to be usable
with any appropriate data structure.
FIXME FIXME say more here
=cut
##
##
##
=for position post_methods
=head1 CREATING A CUSTOM TREE MODEL
GTK+ provides two model implementations, Gtk2::TreeStore and Gtk2::ListStore,
which should be sufficient in most cases. For some cases, however, it is
advantageous to provide a custom tree model implementation. It is possible
to create custom tree models in Perl, because we're cool like that.
To do this, you create a Glib::Object derivative which implements the
Gtk2::TreeModel interface; this is gtk2-perl-speak for "you have to add
a special key when you register your object type." For example:
package MyModel;
use Gtk2;
use Glib::Object::Subclass
Glib::Object::,
interfaces => [ Gtk2::TreeModel:: ],
;
This will cause perl to call several virtual methods with ALL_CAPS_NAMES
when Gtk+ attempts to perform certain actions on the model. You simply
provide (or override) those methods.
=head2 TREE ITERS
Gtk2::TreeIter is normally an opaque object, but on the implementation side
of a Gtk2::TreeModel, you have to define what's inside. The virtual methods
described below deal with iters as a reference to an array containing four
values:
=over
=item o stamp (integer)
A number unique to this model.
=item o user_data (integer)
An arbitrary integer value.
=item o user_data2 (scalar)
An arbitrary scalar. Will not persist. May be undef.
=item o user_data3 (scalar)
An arbitrary scalar. Will not persist. May be undef.
=back
=head2 VIRTUAL METHODS
An implementation of
=over
=item treemodelflags = GET_FLAGS ($model)
=item integer = GET_N_COLUMNS ($model)
=item string = GET_COLUMN_TYPE ($model, $index)
=item ARRAYREF = GET_ITER ($model, $path)
See above for a description of what goes in the returned array reference.
=item treepath = GET_PATH ($model, ARRAYREF)
=item scalar = GET_VALUE ($model, ARRAYREF, $column)
Implements $treemodel->get().
=item ARRAYREF = ITER_NEXT ($model, ARRAYREF)
=item ARRAYREF = ITER_CHILDREN ($model, ARRAYREF)
=item boolean = ITER_HAS_CHILD ($model, ARRAYREF)
=item integer = ITER_N_CHILDREN ($model, ARRAYREF)
=item ARRAYREF = ITER_NTH_CHILD ($model, ARRAYREF, $n)
=item ARRAYREF = ITER_PARENT ($model, ARRAYREF)
=item REF_NODE ($model, ARRAYREF)
Optional.
=item REF_NODE ($model, ARRAYREF)
Optional.
=back
=cut
=for apidoc __hide__
=cut
void
_ADD_INTERFACE (class, const char * target_class)
CODE:
{
static const GInterfaceInfo iface_info = {
(GInterfaceInitFunc) gtk2perl_tree_model_init,
(GInterfaceFinalizeFunc) NULL,
(gpointer) NULL
};
GType gtype = gperl_object_type_from_package (target_class);
g_type_add_interface_static (gtype, GTK_TYPE_TREE_MODEL, &iface_info);
}
MODULE = Gtk2::TreeModel PACKAGE = Gtk2::TreePath PREFIX = gtk_tree_path_
GtkTreePath_own_ornull *
gtk_tree_path_new (class, path=NULL)
const gchar * path
ALIAS:
new_from_string = 1
CODE:
PERL_UNUSED_VAR (ix);
if (path)
RETVAL = gtk_tree_path_new_from_string (path);
else
RETVAL = gtk_tree_path_new ();
OUTPUT:
RETVAL
## GtkTreePath * gtk_tree_path_new_from_indices (gint first_index, ...)
=for apidoc
=for arg first_index (integer) a non-negative index value
=for arg ... of zero or more index values
The C API reference docs for this function say to mark the end of the list
with a -1, but Perl doesn't need list terminators, so don't do that.
This is specially implemented to be available for all gtk+ versions.
=cut
GtkTreePath_own_ornull *
gtk_tree_path_new_from_indices (class, first_index, ...)
PREINIT:
gint i;
GtkTreePath *path;
CODE:
path = gtk_tree_path_new ();
for (i = 1 ; i < items ; i++) {
gint index = SvIV (ST (i));
if (index < 0)
croak ("Gtk2::TreePath->new_from_indices takes index"
" values from the argument stack and therefore"
" does not use a -1 terminator value like its"
" C counterpart; negative index values are"
" not allowed");
gtk_tree_path_append_index (path, index);
}
RETVAL = path;
OUTPUT:
RETVAL
gchar_own *
gtk_tree_path_to_string (path)
GtkTreePath * path
GtkTreePath_own *
gtk_tree_path_new_first (class)
C_ARGS:
/* void */
## gtk_tree_path_new_root is deprecated in 2.2.0
void
gtk_tree_path_append_index (path, index_)
GtkTreePath *path
gint index_
void
gtk_tree_path_prepend_index (path, index_)
GtkTreePath *path
gint index_
gint
gtk_tree_path_get_depth (path)
GtkTreePath *path
=for apidoc
Returns a list of integers.
=cut
void
gtk_tree_path_get_indices (path)
GtkTreePath * path
PREINIT:
gint * indices;
gint depth;
gint i;
PPCODE:
depth = gtk_tree_path_get_depth (path);
indices = gtk_tree_path_get_indices (path);
EXTEND (SP, depth);
for (i = 0 ; i < depth ; i++)
PUSHs (sv_2mortal (newSViv (indices[i])));
## boxed wrapper stuff handled by Glib::Boxed
## GtkTreePath * gtk_tree_path_copy (GtkTreePath *path)
## void gtk_tree_path_free (GtkTreePath *path)
gint
gtk_tree_path_compare (a, b)
GtkTreePath *a
GtkTreePath *b
void
gtk_tree_path_next (path)
GtkTreePath *path
gboolean
gtk_tree_path_prev (path)
GtkTreePath *path
gboolean
gtk_tree_path_up (path)
GtkTreePath *path
void
gtk_tree_path_down (path)
GtkTreePath *path
gboolean
gtk_tree_path_is_ancestor (path, descendant)
GtkTreePath *path
GtkTreePath *descendant
gboolean
gtk_tree_path_is_descendant (path, ancestor)
GtkTreePath *path
GtkTreePath *ancestor
MODULE = Gtk2::TreeModel PACKAGE = Gtk2::TreeRowReference PREFIX = gtk_tree_row_reference_
##
## there doesn't seem to be a GType for GtkTreeRowReference in 2.0.x...
##
#ifdef GTK_TYPE_TREE_ROW_REFERENCE
##GtkTreeRowReference* gtk_tree_row_reference_new (GtkTreeModel *model, GtkTreePath *path);
# $row_ref_or_undef = Gtk2::TreeRowReference->new ($model, $path)
GtkTreeRowReference_own_ornull*
gtk_tree_row_reference_new (class, GtkTreeModel *model, GtkTreePath *path)
C_ARGS:
model, path
## mmmm, the docs say "you do not need to use this function"
##GtkTreeRowReference* gtk_tree_row_reference_new_proxy (GObject *proxy, GtkTreeModel *model, GtkTreePath *path);
GtkTreePath_own_ornull * gtk_tree_row_reference_get_path (GtkTreeRowReference *reference);
## gboolean gtk_tree_row_reference_valid (GtkTreeRowReference *reference)
gboolean
gtk_tree_row_reference_valid (reference)
GtkTreeRowReference *reference
#### boxed wrapper stuff handled by Glib::Boxed
#### GtkTreeRowReference* gtk_tree_row_reference_copy (GtkTreeRowReference *reference);
#### void gtk_tree_row_reference_free (GtkTreeRowReference *reference)
## i gather that you only need these if you created the row reference with
## gtk_tree_row_reference_new_proxy... but they recommend you don't use
## the proxy stuff. i'll hold off until somebody asks for it.
#### void gtk_tree_row_reference_inserted (GObject *proxy, GtkTreePath *path)
##void
##gtk_tree_row_reference_inserted (proxy, path)
## GObject *proxy
## GtkTreePath *path
##
#### void gtk_tree_row_reference_deleted (GObject *proxy, GtkTreePath *path)
##void
##gtk_tree_row_reference_deleted (proxy, path)
## GObject *proxy
## GtkTreePath *path
##
#### void gtk_tree_row_reference_reordered (GObject *proxy, GtkTreePath *path, GtkTreeIter *iter, gint *new_order)
##void
##gtk_tree_row_reference_reordered (proxy, path, iter, new_order)
## GObject *proxy
## GtkTreePath *path
## GtkTreeIter *iter
## gint *new_order
##
#endif /* defined GTK_TYPE_TREE_ROW_REFERENCE */
####MODULE = Gtk2::TreeModel PACKAGE = Gtk2::TreeIter PREFIX = gtk_tree_iter_
## we get this from Glib::Boxed::copy
## GtkTreeIter * gtk_tree_iter_copy (GtkTreeIter * iter)
## we get this from Glib::Boxed::DESTROY
## void gtk_tree_iter_free (GtkTreeIter *iter)
MODULE = Gtk2::TreeModel PACKAGE = Gtk2::TreeModel PREFIX = gtk_tree_model_
BOOT:
gperl_signal_set_marshaller_for (GTK_TYPE_TREE_MODEL, "rows_reordered",
gtk2perl_tree_model_rows_reordered_marshal);
=for flags GtkTreeModelFlags
=cut
## GtkTreeModelFlags gtk_tree_model_get_flags (GtkTreeModel *tree_model)
GtkTreeModelFlags
gtk_tree_model_get_flags (tree_model)
GtkTreeModel *tree_model
## gint gtk_tree_model_get_n_columns (GtkTreeModel *tree_model)
gint
gtk_tree_model_get_n_columns (tree_model)
GtkTreeModel *tree_model
## GType gtk_tree_model_get_column_type (GtkTreeModel *tree_model, gint index_)
### we hide GType from the perl level. return the corresponding
### package instead.
=for apidoc
Returns the type of column I<$index_> as a package name.
=cut
const gchar *
gtk_tree_model_get_column_type (tree_model, index_)
GtkTreeModel *tree_model
gint index_
PREINIT:
GType t;
CODE:
t = gtk_tree_model_get_column_type (tree_model, index_);
RETVAL = gperl_package_from_type (t);
if (!RETVAL)
croak ("internal -- type of column %d, %s (%d), is not registered with GPerl",
index_, g_type_name (t), t);
OUTPUT:
RETVAL
## gboolean gtk_tree_model_get_iter (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path)
GtkTreeIter_copy *
gtk_tree_model_get_iter (tree_model, path)
GtkTreeModel *tree_model
GtkTreePath *path
PREINIT:
GtkTreeIter iter = {0, };
CODE:
if (!gtk_tree_model_get_iter (tree_model, &iter, path))
XSRETURN_UNDEF;
RETVAL = &iter;
OUTPUT:
RETVAL
##### FIXME couldn't we combine get_iter and get_iter_from_string, since we'll
##### be able to tell at runtime whether the arg is a GtkTreePath or a
##### plain old string?
## gboolean gtk_tree_model_get_iter_from_string (GtkTreeModel *tree_model, GtkTreeIter *iter, const gchar *path_string)
GtkTreeIter_copy *
gtk_tree_model_get_iter_from_string (tree_model, path_string)
GtkTreeModel *tree_model
const gchar *path_string
PREINIT:
GtkTreeIter iter = {0, };
CODE:
if (!gtk_tree_model_get_iter_from_string (tree_model, &iter, path_string))
XSRETURN_UNDEF;
RETVAL = &iter;
OUTPUT:
RETVAL
#if GTK_CHECK_VERSION(2,2,0)
## gchar * gtk_tree_model_get_string_from_iter (GtkTreeModel *tree_model, GtkTreeIter *iter)
gchar_own *
gtk_tree_model_get_string_from_iter (tree_model, iter)
GtkTreeModel *tree_model
GtkTreeIter *iter
#endif /* 2.2.0 */
## gboolean gtk_tree_model_get_iter_first (GtkTreeModel *tree_model, GtkTreeIter *iter)
GtkTreeIter_copy *
gtk_tree_model_get_iter_first (tree_model)
GtkTreeModel *tree_model
PREINIT:
GtkTreeIter iter = {0, };
CODE:
if (!gtk_tree_model_get_iter_first (tree_model, &iter))
XSRETURN_UNDEF;
RETVAL = &iter;
OUTPUT:
RETVAL
### gtk_tree_model_get_iter_root is deprecated
## GtkTreePath * gtk_tree_model_get_path (GtkTreeModel *tree_model, GtkTreeIter *iter)
GtkTreePath_own *
gtk_tree_model_get_path (tree_model, iter)
GtkTreeModel *tree_model
GtkTreeIter *iter
## void gtk_tree_model_get (GtkTreeModel *tree_model, GtkTreeIter *iter, ...)
## void gtk_tree_model_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value)
=for apidoc get_value
=for arg ... of column indices
Alias for L<get|list = $tree_model-E<gt>get ($iter, ...)>.
=cut
=for apidoc
=for arg ... of column indices
Fetch and return the model's values in the row pointed to by I<$iter>.
If you specify no column indices, it returns the values for all of the
columns, otherwise, returns just those columns' values (in order).
This overrides overrides Glib::Object's C<get>, so you'll want to use
C<< $object->get_property >> to get object properties.
=cut
void
gtk_tree_model_get (tree_model, iter, ...)
GtkTreeModel *tree_model
GtkTreeIter *iter
ALIAS:
get_value = 1
PREINIT:
int i;
PPCODE:
PERL_UNUSED_VAR (ix);
/* if column id's were passed, just return those columns */
if( items > 2 )
{
for (i = 2 ; i < items ; i++) {
GValue gvalue = {0, };
gtk_tree_model_get_value (tree_model, iter,
SvIV (ST (i)), &gvalue);
XPUSHs (sv_2mortal (gperl_sv_from_value (&gvalue)));
g_value_unset (&gvalue);
}
}
else
{
/* otherwise return all of the columns */
for( i = 0; i < gtk_tree_model_get_n_columns(tree_model); i++ )
{
GValue gvalue = {0, };
gtk_tree_model_get_value (tree_model, iter,
i, &gvalue);
XPUSHs (sv_2mortal (gperl_sv_from_value (&gvalue)));
g_value_unset (&gvalue);
}
}
## va_list means nothing to a perl developer, it's a c-specific thing.
#### void gtk_tree_model_get_valist (GtkTreeModel *tree_model, GtkTreeIter *iter, va_list var_args)
##
## gboolean gtk_tree_model_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter)
GtkTreeIter_own *
gtk_tree_model_iter_next (tree_model, iter)
GtkTreeModel *tree_model
GtkTreeIter *iter
CODE:
/* the C version modifies the iter we pass; to make this fit more
* with the rest of our Perl interface, we want *not* to modify
* the one passed and instead return the modified iter... which
* means we have to copy *first*. */
RETVAL = gtk_tree_iter_copy (iter);
if (!gtk_tree_model_iter_next (tree_model, RETVAL)) {
gtk_tree_iter_free (RETVAL);
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
#### gboolean gtk_tree_model_iter_children (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent)
GtkTreeIter_copy *
gtk_tree_model_iter_children (tree_model, parent)
GtkTreeModel *tree_model
GtkTreeIter_ornull *parent
PREINIT:
GtkTreeIter iter;
CODE:
if (!gtk_tree_model_iter_children (tree_model, &iter, parent))
XSRETURN_UNDEF;
RETVAL = &iter;
OUTPUT:
RETVAL
## gboolean gtk_tree_model_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter)
gboolean
gtk_tree_model_iter_has_child (tree_model, iter)
GtkTreeModel *tree_model
GtkTreeIter *iter
## gint gtk_tree_model_iter_n_children (GtkTreeModel *tree_model, GtkTreeIter *iter)
gint
gtk_tree_model_iter_n_children (tree_model, iter=NULL)
GtkTreeModel *tree_model
GtkTreeIter_ornull *iter
## gboolean gtk_tree_model_iter_nth_child (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n)
GtkTreeIter_copy *
gtk_tree_model_iter_nth_child (tree_model, parent, n)
GtkTreeModel *tree_model
GtkTreeIter_ornull *parent
gint n
PREINIT:
GtkTreeIter iter;
CODE:
if (!gtk_tree_model_iter_nth_child (tree_model, &iter, parent, n))
XSRETURN_UNDEF;
RETVAL = &iter;
OUTPUT:
RETVAL
## gboolean gtk_tree_model_iter_parent (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child)
GtkTreeIter_copy *
gtk_tree_model_iter_parent (tree_model, child)
GtkTreeModel *tree_model
GtkTreeIter *child
PREINIT:
GtkTreeIter iter;
CODE:
if (! gtk_tree_model_iter_parent (tree_model, &iter, child))
XSRETURN_UNDEF;
RETVAL = &iter;
OUTPUT:
RETVAL
## void gtk_tree_model_ref_node (GtkTreeModel *tree_model, GtkTreeIter *iter)
void
gtk_tree_model_ref_node (tree_model, iter)
GtkTreeModel *tree_model
GtkTreeIter *iter
## void gtk_tree_model_unref_node (GtkTreeModel *tree_model, GtkTreeIter *iter)
void
gtk_tree_model_unref_node (tree_model, iter)
GtkTreeModel *tree_model
GtkTreeIter *iter
## void gtk_tree_model_foreach (GtkTreeModel *model, GtkTreeModelForeachFunc func, gpointer user_data)
=for apidoc
=for arg func (subroutine)
Call I<$func> on each row in I<$model>. I<$func> gets the tree path and iter
of the current row; if I<$func> returns true, the tree ceases to be walked,
and C<< $treemodel->foreach >> returns.
=cut
void
gtk_tree_model_foreach (model, func, user_data=NULL)
GtkTreeModel *model
SV * func
SV * user_data
PREINIT:
GPerlCallback * callback;
GType types[3];
CODE:
types[0] = GTK_TYPE_TREE_MODEL;
types[1] = GTK_TYPE_TREE_PATH;
types[2] = GTK_TYPE_TREE_ITER;
callback = gperl_callback_new (func, user_data, G_N_ELEMENTS (types), types,
G_TYPE_BOOLEAN);
gtk_tree_model_foreach (model, gtk2perl_tree_model_foreach_func, callback);
gperl_callback_destroy (callback);
## void gtk_tree_model_row_changed (GtkTreeModel *tree_model, GtkTreePath *path, GtkTreeIter *iter)
=for apidoc
Emits the "row_changed" signal on I<$tree_model>.
=cut
void
gtk_tree_model_row_changed (tree_model, path, iter)
GtkTreeModel *tree_model
GtkTreePath *path
GtkTreeIter *iter
## void gtk_tree_model_row_inserted (GtkTreeModel *tree_model, GtkTreePath *path, GtkTreeIter *iter)
=for apidoc
Emits the "row_inserted" signal on I<$tree_model>.
=cut
void
gtk_tree_model_row_inserted (tree_model, path, iter)
GtkTreeModel *tree_model
GtkTreePath *path
GtkTreeIter *iter
## void gtk_tree_model_row_has_child_toggled (GtkTreeModel *tree_model, GtkTreePath *path, GtkTreeIter *iter)
=for apidoc
Emits the "row_has_child_toggled" signal on I<$tree_model>. This should be
called by models after the child state of a node changes.
=cut
void
gtk_tree_model_row_has_child_toggled (tree_model, path, iter)
GtkTreeModel *tree_model
GtkTreePath *path
GtkTreeIter *iter
## void gtk_tree_model_row_deleted (GtkTreeModel *tree_model, GtkTreePath *path)
=for apidoc
Emits the "row_deleted" signal on I<$tree_model>. This should be called by
models after a row has been removed. The location pointed to by I<$path>
should be the removed row's old location. It may not be a valid location
anymore.
=cut
void
gtk_tree_model_row_deleted (tree_model, path)
GtkTreeModel *tree_model
GtkTreePath *path
#### void gtk_tree_model_rows_reordered (GtkTreeModel *tree_model, GtkTreePath *path, GtkTreeIter *iter, gint *new_order)
=for apidoc
=for arg path the tree node whose children have been reordered
=for arg iter the tree node whose children have been reordered
=for arg ... (integers) array of integers mapping the current position of each child to its old position before the re-ordering, i.e. $new_order[$newpos] = $oldpos. There should be as many elements in this list as there are rows in I<$tree_model>.
Emits the "rows-reordered" signal on I<$tree_model>/ This should be called
by models with their rows have been reordered.
=cut
void
gtk_tree_model_rows_reordered (tree_model, path, iter, ...)
GtkTreeModel *tree_model
GtkTreePath *path
GtkTreeIter_ornull *iter
PREINIT:
gint *new_order;
int n, i;
CODE:
n = gtk_tree_model_iter_n_children (tree_model, iter);
if (items - 3 != n)
croak ("rows_reordered expects a list of as many indices"
" as the selected node of the model has children\n"
" got %d, expected %d", items - 3, n);
new_order = g_new (gint, n);
for (i = 0 ; i < n ; i++)
new_order[i] = SvIV (ST (3+i));
gtk_tree_model_rows_reordered (tree_model, path, iter, new_order);
g_free (new_order);