[Gtk-sharp-list] patch: managed TreeModel impl

Vladimir Vukicevic vladimirv@gmail.com
Sat, 29 May 2004 21:53:24 -0700


------=_Part_127_30261212.1085892804612
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Okay, round 2!  Only a small patch is needed now, basically to remove
the SetValue() stuff from the TreeModel interface, and to add the
UserData1-3 bits to TreeIter.  I'm really not happy with the UserData
bits; like I said in a previous email, I'm looking into seeing if we
can trust RefNode/UnrefNode so that we can keep a hash table around,
but from looking at traces, I don't think I can trust that.

I've also attached a NodeStore implemented on top of ManagedTreeModel;
it compiles, but is untested as I didn't have a NodeStore demo
anywhere -- does one exist?

    - Vlad

------=_Part_127_30261212.1085892804612
Content-Type: text/x-patch; name="mtm.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="mtm.patch"

Index: gtk/TreeIter.custom
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvs/public/gtk-sharp/gtk/TreeIter.custom,v
retrieving revision 1.3
diff -u -u -r1.3 TreeIter.custom
--- gtk/TreeIter.custom=0912 Feb 2004 21:28:42 -0000=091.3
+++ gtk/TreeIter.custom=0930 May 2004 04:02:46 -0000
@@ -19,3 +19,18 @@
                                 ti._user_data2 =3D=3D _user_data2 &&
                                 ti._user_data3 =3D=3D _user_data3;
                 }
+
+                public IntPtr UserData1 {
+                        get { return _user_data; }
+                        set { _user_data =3D value; }
+                }
+               =20
+                public IntPtr UserData2 {
+                        get { return _user_data2; }
+                        set { _user_data2 =3D value; }
+                }
+               =20
+                public IntPtr UserData3 {
+                        get { return _user_data3; }
+                        set { _user_data3 =3D value; }
+                }
Index: gtk/TreeModel.custom
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvs/public/gtk-sharp/gtk/TreeModel.custom,v
retrieving revision 1.2
diff -u -u -r1.2 TreeModel.custom
--- gtk/TreeModel.custom=091 Nov 2003 12:00:26 -0000=091.2
+++ gtk/TreeModel.custom=0930 May 2004 04:02:46 -0000
@@ -18,11 +18,6 @@
 =09/// <remarks>To be completed</remarks>
 =09bool IterNthChild (out Gtk.TreeIter iter, int n);
=20
-        void SetValue (Gtk.TreeIter iter, int column, bool value);
-        void SetValue (Gtk.TreeIter iter, int column, double value);
-=09void SetValue (Gtk.TreeIter iter, int column, int value);
-=09void SetValue (Gtk.TreeIter iter, int column, string value);
-=09void SetValue (Gtk.TreeIter iter, int column, float value);
-=09void SetValue (Gtk.TreeIter iter, int column, uint value);
-=09void SetValue (Gtk.TreeIter iter, int column, object value);
+=09/// <summary>GetValue Method</summary>
+=09/// <remarks>To be completed</remarks>
 =09object GetValue(Gtk.TreeIter iter, int column);

------=_Part_127_30261212.1085892804612
Content-Type: text/x-csharp; name="ManagedTreeModel.cs"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="ManagedTreeModel.cs"

//
// ManagedTreeModel.cs
//
// Managed framework for implementing TreeModels
//
// Author(s): Vladimir Vukicevic  <vladimir@pobox.com>

namespace Gtk {
=09using System;
=09using System.Collections;
=09using System.Runtime.InteropServices;

=09public abstract class ManagedTreeModel : GLib.Object, TreeModel {

=09=09//
=09=09// TreeModel interface
=09=09//

=09=09//
=09=09// These are things that can be overriden by subclasses
=09=09//

=09=09public virtual Gtk.TreeModelFlags Flags {
=09=09=09get {
=09=09=09=09return (Gtk.TreeModelFlags) 0;
=09=09=09}
=09=09}

=09=09public abstract int NColumns { get; }

=09=09public abstract System.Type ColumnType (int index);

=09=09public virtual GLib.GType GetColumnType (int index) {
=09=09=09return GLib.TypeConverter.LookupType (ColumnType (index));
=09=09}

=09=09public abstract bool GetIter (out Gtk.TreeIter iter, Gtk.TreePath pat=
h);

=09=09public abstract Gtk.TreePath GetPath (Gtk.TreeIter iter);

=09=09public abstract object GetValue (Gtk.TreeIter iter, int column);

=09=09public virtual void GetValue (Gtk.TreeIter iter, int column, ref GLib=
.Value value) {
=09=09=09object o =3D GetValue (iter, column);
=09=09=09if (o =3D=3D null) {
=09=09=09=09value.Init (GLib.GType.Invalid);
=09=09=09=09return;
=09=09=09}
=09=09=09GLib.GType ctype =3D GLib.TypeConverter.LookupType (o.GetType());
=09=09=09value.Init (ctype);
=09=09=09value.Val =3D o;
=09=09}

=09=09public abstract bool IterNext (ref Gtk.TreeIter iter);

=09=09public virtual bool IterHasChild (Gtk.TreeIter iter) {
=09=09=09return false;
=09=09}

=09=09public virtual bool IterChildren (out Gtk.TreeIter iter, Gtk.TreeIter=
 parent) {
=09=09=09iter =3D TreeIter.Zero;
=09=09=09return false;
=09=09}

=09=09public virtual int IterNChildren (Gtk.TreeIter iter) {
=09=09=09return 0;
=09=09}

=09=09public virtual bool IterNthChild (out Gtk.TreeIter iter, Gtk.TreeIter=
 parent, int n) {
=09=09=09iter =3D TreeIter.Zero;
=09=09=09return false;
=09=09}

=09=09public virtual bool IterParent (out Gtk.TreeIter iter, Gtk.TreeIter c=
hild) {
=09=09=09iter =3D TreeIter.Zero;
=09=09=09return false;
=09=09}

=09=09public virtual void RefNode (Gtk.TreeIter iter) {
=09=09=09// nothing
=09=09}

=09=09public virtual void UnrefNode (Gtk.TreeIter iter) {
=09=09=09// nothing
=09=09}

=09=09// events

=09=09public event Gtk.RowChangedHandler RowChanged {
=09=09=09add {
=09=09=09=09System.ComponentModel.EventHandlerList event_list =3D AfterHand=
lers;
=09=09=09=09Hashtable signals =3D AfterSignals;
=09=09=09=09if (value.Method.GetCustomAttributes (typeof(GLib.ConnectBefore=
Attribute), false).Length > 0) {
=09=09=09=09=09event_list =3D BeforeHandlers;
=09=09=09=09=09signals =3D BeforeSignals;
=09=09=09=09}

=09=09=09=09if (signals["row_changed"] =3D=3D null)
=09=09=09=09=09signals["row_changed"] =3D new GtkSharp.voidObjectTreePathTr=
eeIterSignal
=09=09=09=09=09=09(this, "row_changed", value, System.Type.GetType("Gtk.Row=
ChangedHandler,gtk-sharp"), 0);
=09=09=09=09else
=09=09=09=09=09((GLib.SignalCallback) signals["row_changed"]).AddDelegate (=
value);

=09=09=09=09event_list.AddHandler("row_changed", value);
=09=09=09}

=09=09=09remove {
=09=09=09=09sigRemovalHelper (value, "row_changed");
=09=09=09}
=09=09}

=09=09public event Gtk.RowDeletedHandler RowDeleted {
=09=09=09add {
=09=09=09=09System.ComponentModel.EventHandlerList event_list =3D AfterHand=
lers;
=09=09=09=09Hashtable signals =3D AfterSignals;
=09=09=09=09if (value.Method.GetCustomAttributes (typeof(GLib.ConnectBefore=
Attribute), false).Length > 0) {
=09=09=09=09=09event_list =3D BeforeHandlers;
=09=09=09=09=09signals =3D BeforeSignals;
=09=09=09=09}

=09=09=09=09if (signals["row_deleted"] =3D=3D null)
=09=09=09=09=09signals["row_deleted"] =3D new GtkSharp.voidObjectTreePathSi=
gnal
=09=09=09=09=09=09(this, "row_deleted", value, System.Type.GetType("Gtk.Row=
DeletedHandler,gtk-sharp"), 0);
=09=09=09=09else
=09=09=09=09=09((GLib.SignalCallback) signals["row_deleted"]).AddDelegate (=
value);

=09=09=09=09event_list.AddHandler("row_deleted", value);
=09=09=09}

=09=09=09remove {
=09=09=09=09sigRemovalHelper (value, "row_deleted");
=09=09=09}
=09=09}

=09=09public event Gtk.RowHasChildToggledHandler RowHasChildToggled {
=09=09=09add {
=09=09=09=09System.ComponentModel.EventHandlerList event_list =3D AfterHand=
lers;
=09=09=09=09Hashtable signals =3D AfterSignals;
=09=09=09=09if (value.Method.GetCustomAttributes (typeof(GLib.ConnectBefore=
Attribute), false).Length > 0) {
=09=09=09=09=09event_list =3D BeforeHandlers;
=09=09=09=09=09signals =3D BeforeSignals;
=09=09=09=09}

=09=09=09=09if (signals["row_has_child_toggled"] =3D=3D null)
=09=09=09=09=09signals["row_has_child_toggled"] =3D new GtkSharp.voidObject=
TreePathTreeIterSignal
=09=09=09=09=09=09(this, "row_has_child_toggled", value, System.Type.GetTyp=
e("Gtk.RowHasChildToggledHandler,gtk-sharp"), 0);
=09=09=09=09else
=09=09=09=09=09((GLib.SignalCallback) signals["row_has_child_toggled"]).Add=
Delegate (value);

=09=09=09=09event_list.AddHandler("row_has_child_toggled", value);
=09=09=09}

=09=09=09remove {
=09=09=09=09sigRemovalHelper (value, "row_has_child_toggled");
=09=09=09}
=09=09}

=09=09public event Gtk.RowInsertedHandler RowInserted {
=09=09=09add {
=09=09=09=09System.ComponentModel.EventHandlerList event_list =3D AfterHand=
lers;
=09=09=09=09Hashtable signals =3D AfterSignals;
=09=09=09=09if (value.Method.GetCustomAttributes (typeof(GLib.ConnectBefore=
Attribute), false).Length > 0) {
=09=09=09=09=09event_list =3D BeforeHandlers;
=09=09=09=09=09signals =3D BeforeSignals;
=09=09=09=09}

=09=09=09=09if (signals["row_inserted"] =3D=3D null)
=09=09=09=09=09signals["row_inserted"] =3D new GtkSharp.voidObjectTreePathT=
reeIterSignal
=09=09=09=09=09=09(this, "row_inserted", value, System.Type.GetType("Gtk.Ro=
wInsertedHandler,gtk-sharp"), 0);
=09=09=09=09else
=09=09=09=09=09((GLib.SignalCallback) signals["row_inserted"]).AddDelegate =
(value);

=09=09=09=09event_list.AddHandler("row_inserted", value);
=09=09=09}

=09=09=09remove {
=09=09=09=09sigRemovalHelper (value, "row_inserted");
=09=09=09}
=09=09}

=09=09public event Gtk.RowsReorderedHandler RowsReordered {
=09=09=09add {
=09=09=09=09System.ComponentModel.EventHandlerList event_list =3D AfterHand=
lers;
=09=09=09=09Hashtable signals =3D AfterSignals;
=09=09=09=09if (value.Method.GetCustomAttributes (typeof(GLib.ConnectBefore=
Attribute), false).Length > 0) {
=09=09=09=09=09event_list =3D BeforeHandlers;
=09=09=09=09=09signals =3D BeforeSignals;
=09=09=09=09}

=09=09=09=09if (signals["rows_reordered"] =3D=3D null)
=09=09=09=09=09signals["rows_reordered"] =3D new GtkSharp.voidObjectTreePat=
hTreeIterintSignal
=09=09=09=09=09=09(this, "rows_reordered", value, System.Type.GetType("Gtk.=
RowsReorderedHandler,gtk-sharp"), 0);
=09=09=09=09else
=09=09=09=09=09((GLib.SignalCallback) signals["rows_reordered"]).AddDelegat=
e (value);

=09=09=09=09event_list.AddHandler("rows_reordered", value);
=09=09=09}

=09=09=09remove {
=09=09=09=09sigRemovalHelper (value, "rows_reordered");
=09=09=09}
=09=09}

=09=09private void sigRemovalHelper (Delegate d, string signame) {
=09=09=09System.ComponentModel.EventHandlerList event_list =3D AfterHandler=
s;
=09=09=09Hashtable signals =3D AfterSignals;
=09=09=09if (d.Method.GetCustomAttributes(typeof(GLib.ConnectBeforeAttribut=
e), false).Length > 0) {
=09=09=09=09event_list =3D BeforeHandlers;
=09=09=09=09signals =3D BeforeSignals;
=09=09=09}
=09=09=09GLib.SignalCallback cb =3D signals[signame] as GLib.SignalCallback=
;
=09=09=09event_list.RemoveHandler(signame, d);
=09=09=09if (cb =3D=3D null)
=09=09=09=09return;

=09=09=09cb.RemoveDelegate(d);

=09=09=09if (event_list["rows_reordered"] =3D=3D null) {
=09=09=09=09signals.Remove("rows_reordered");
=09=09=09=09cb.Dispose ();
=09=09=09}
=09=09}

=09=09/*
=09=09 * These are methods that are defined on tree_model, but are not part=
 of the interface itself.
=09=09 * This code is duplicated in ListStore and TreeStore, which sucks; t=
here really should be a way
=09=09 * to have a common ancestor for these.
=09=09 */

=09=09[DllImport("libgtk-win32-2.0-0.dll")]
=09=09static extern void gtk_tree_model_get_valist(IntPtr raw, ref Gtk.Tree=
Iter iter, IntPtr var_args);
   =20
=09=09public void GetValist(Gtk.TreeIter iter, IntPtr var_args) {
=09=09=09gtk_tree_model_get_valist(Handle, ref iter, var_args);
=09=09}

=09=09[DllImport("libgtk-win32-2.0-0.dll")]
=09=09static extern IntPtr gtk_tree_model_get_string_from_iter(IntPtr raw, =
ref Gtk.TreeIter iter);

=09=09public string GetStringFromIter(Gtk.TreeIter iter) {
=09=09=09IntPtr raw_ret =3D gtk_tree_model_get_string_from_iter(Handle, ref=
 iter);
=09=09=09string ret =3D GLib.Marshaller.PtrToStringGFree(raw_ret);
=09=09=09return ret;
=09=09}

=09=09[DllImport("libgtk-win32-2.0-0.dll")]
=09=09static extern bool gtk_tree_model_get_iter_from_string(IntPtr raw, ou=
t Gtk.TreeIter iter, string path_string);

=09=09public bool GetIterFromString(out Gtk.TreeIter iter, string path_stri=
ng) {
=09=09=09bool raw_ret =3D gtk_tree_model_get_iter_from_string(Handle, out i=
ter, path_string);
=09=09=09bool ret =3D raw_ret;
=09=09=09return ret;
=09=09}


=09=09[DllImport("libgtk-win32-2.0-0.dll")]
=09=09static extern bool gtk_tree_model_get_iter_first(IntPtr raw, out Gtk.=
TreeIter iter);

=09=09public bool GetIterFirst(out Gtk.TreeIter iter) {
=09=09=09bool raw_ret =3D gtk_tree_model_get_iter_first(Handle, out iter);
=09=09=09bool ret =3D raw_ret;
=09=09=09return ret;
=09=09}

=09=09[DllImport("libgtk-win32-2.0-0.dll")]
=09=09static extern void gtk_tree_model_foreach(IntPtr raw, GtkSharp.TreeMo=
delForeachFuncNative func, IntPtr user_data);

=09=09public void Foreach(Gtk.TreeModelForeachFunc func) {
=09=09=09GtkSharp.TreeModelForeachFuncWrapper func_wrapper =3D null;
=09=09=09func_wrapper =3D new GtkSharp.TreeModelForeachFuncWrapper (func, t=
his);
=09=09=09gtk_tree_model_foreach(Handle, func_wrapper.NativeDelegate, IntPtr=
.Zero);
=09=09}


=09=09/* Signal emitters */
=09=09[DllImport("libgtk-win32-2.0-0.dll")]
=09=09static extern void gtk_tree_model_row_changed(IntPtr raw, IntPtr path=
, ref Gtk.TreeIter iter);

=09=09public void EmitRowChanged(Gtk.TreePath path, Gtk.TreeIter iter) {
=09=09=09gtk_tree_model_row_changed(Handle, path.Handle, ref iter);
=09=09}

=09=09[DllImport("libgtk-win32-2.0-0.dll")]
=09=09static extern void gtk_tree_model_row_deleted(IntPtr raw, IntPtr path=
);

=09=09public void EmitRowDeleted(Gtk.TreePath path) {
=09=09=09gtk_tree_model_row_deleted(Handle, path.Handle);
=09=09}

=09=09[DllImport("libgtk-win32-2.0-0.dll")]
=09=09static extern void gtk_tree_model_row_inserted(IntPtr raw, IntPtr pat=
h, ref Gtk.TreeIter iter);

=09=09public void EmitRowInserted(Gtk.TreePath path, Gtk.TreeIter iter) {
=09=09=09gtk_tree_model_row_inserted(Handle, path.Handle, ref iter);
=09=09}

=09=09[DllImport("libgtk-win32-2.0-0.dll")]
=09=09static extern void gtk_tree_model_row_has_child_toggled(IntPtr raw, I=
ntPtr path, ref Gtk.TreeIter iter);

=09=09public void EmitRowHasChildToggled(Gtk.TreePath path, Gtk.TreeIter it=
er) {
=09=09=09gtk_tree_model_row_has_child_toggled(Handle, path.Handle, ref iter=
);
=09=09}

=09=09[DllImport("libgtk-win32-2.0-0.dll")]
=09=09static extern void gtk_tree_model_rows_reordered(IntPtr raw, IntPtr p=
ath, ref Gtk.TreeIter iter, out int new_order);

=09=09public int EmitRowsReordered(Gtk.TreePath path, Gtk.TreeIter iter) {
=09=09=09int new_order;
=09=09=09gtk_tree_model_rows_reordered(Handle, path.Handle, ref iter, out n=
ew_order);
=09=09=09return new_order;
=09=09}

=09=09/* Convenience bits */

=09=09[DllImport("libgtk-win32-2.0-0.dll")]
=09=09static extern bool gtk_tree_model_iter_children (IntPtr raw, ref Gtk.=
TreeIter iter, IntPtr parent);

=09=09public bool IterChildren (ref Gtk.TreeIter iter) {
=09=09=09bool raw_ret =3D gtk_tree_model_iter_children (Handle, ref iter, I=
ntPtr.Zero);
=09=09=09bool ret =3D raw_ret;
=09=09=09return ret;
=09=09}

=09=09[DllImport("libgtk-win32-2.0-0.dll")]
=09=09static extern int gtk_tree_model_iter_n_children (IntPtr raw, IntPtr =
iter);

=09=09public int IterNChildren () {
=09=09=09int raw_ret =3D gtk_tree_model_iter_n_children (Handle, IntPtr.Zer=
o);
=09=09=09int ret =3D raw_ret;
=09=09=09return ret;
=09=09}

=09=09[DllImport("libgtk-win32-2.0-0.dll")]
=09=09static extern bool gtk_tree_model_iter_nth_child (IntPtr raw, ref Gtk=
.TreeIter iter, IntPtr parent, int n);

=09=09public bool IterNthChild (ref Gtk.TreeIter iter, int n) {
=09=09=09bool raw_ret =3D gtk_tree_model_iter_nth_child (Handle, ref iter, =
IntPtr.Zero, n);
=09=09=09bool ret =3D raw_ret;
=09=09=09return ret;
=09=09}

=09=09/*
=09=09 * ManagedTreeModel impl details.  Places where it's valid to pass
=09=09 * in NULL for a TreeIter are passed in as IntPtrs and marshalled
=09=09 * later.  These are in-only structs, so we don't have to marshal bac=
k.
=09=09 */

=09=09internal delegate int TreeModelGetFlagsDelegate (IntPtr tree_model);
=09=09internal delegate int TreeModelGetNColumnsDelegate (IntPtr tree_model=
);
=09=09internal delegate IntPtr TreeModelGetColumnTypeDelegate (IntPtr tree_=
model, int index);
=09=09internal delegate bool TreeModelGetIterDelegate (IntPtr tree_model, o=
ut TreeIter iter, IntPtr path);
=09=09internal delegate IntPtr /* path */ TreeModelGetPathDelegate (IntPtr =
tree_model, /* ref TreeIter */ IntPtr iter);
=09=09internal delegate void TreeModelGetValueDelegate (IntPtr tree_model, =
ref TreeIter iter, int column, ref GLib.Value value);
=09=09internal delegate bool TreeModelIterNextDelegate (IntPtr tree_model, =
ref TreeIter iter);
=09=09internal delegate bool TreeModelIterChildrenDelegate (IntPtr tree_mod=
el, ref TreeIter iter, /* ref TreeIter */ IntPtr parent);
=09=09internal delegate bool TreeModelIterHasChildDelegate (IntPtr tree_mod=
el, /* ref TreeIter */ IntPtr iter);
=09=09internal delegate int TreeModelIterNChildrenDelegate (IntPtr tree_mod=
el, /* ref TreeIter */ IntPtr iter);
=09=09internal delegate bool TreeModelIterNthChildDelegate (IntPtr tree_mod=
el, out TreeIter iter, /* ref TreeIter */ IntPtr parent, int n);
=09=09internal delegate bool TreeModelIterParentDelegate (IntPtr tree_model=
, ref TreeIter iter, ref TreeIter child);
=09=09internal delegate void TreeModelRefNodeDelegate (IntPtr tree_model, r=
ef TreeIter iter);
=09=09internal delegate void TreeModelUnrefNodeDelegate (IntPtr tree_model,=
 ref TreeIter iter);

=09=09/* This is a copy of the TreeModel interface struct */
=09=09[StructLayout(LayoutKind.Sequential)]
=09=09=09internal struct TreeModelInterface {
=09=09=09=09/* GLib.GTypeInterface */
=09=09=09=09internal IntPtr g_type;
=09=09=09=09internal IntPtr g_instance_type;

=09=09=09=09/* GtkTreeModel */
=09=09=09=09/* signals */
=09=09=09=09internal IntPtr row_changed;
=09=09=09=09internal IntPtr row_inserted;
=09=09=09=09internal IntPtr row_has_child_toggled;
=09=09=09=09internal IntPtr row_deleted;
=09=09=09=09internal IntPtr rows_reordered;

=09=09=09=09/* vtbl */
=09=09=09=09internal TreeModelGetFlagsDelegate get_flags;
=09=09=09=09internal TreeModelGetNColumnsDelegate get_n_columns;
=09=09=09=09internal TreeModelGetColumnTypeDelegate get_column_type;
=09=09=09=09internal TreeModelGetIterDelegate get_iter;
=09=09=09=09internal TreeModelGetPathDelegate get_path;
=09=09=09=09internal TreeModelGetValueDelegate get_value;
=09=09=09=09internal TreeModelIterNextDelegate iter_next;
=09=09=09=09internal TreeModelIterChildrenDelegate iter_children;
=09=09=09=09internal TreeModelIterHasChildDelegate iter_has_child;
=09=09=09=09internal TreeModelIterNChildrenDelegate iter_n_children;
=09=09=09=09internal TreeModelIterNthChildDelegate iter_nth_child;
=09=09=09=09internal TreeModelIterParentDelegate iter_parent;
=09=09=09=09internal TreeModelRefNodeDelegate ref_node;
=09=09=09=09internal TreeModelUnrefNodeDelegate unref_node;
=09=09=09}

=09=09// internal delegate void GTreeModelInterfaceInitFuncDelegate (ref Tr=
eeModelInterface iface, IntPtr data);
=09=09internal delegate void GTreeModelInterfaceInitFuncDelegate (IntPtr if=
ace, IntPtr data);
=09=09internal delegate void GTreeModelInterfaceFinalizeFuncDelegate (IntPt=
r iface, IntPtr data);

=09=09[StructLayout(LayoutKind.Sequential)]
=09=09=09internal struct GInterfaceInfo {
=09=09=09=09internal GTreeModelInterfaceInitFuncDelegate init_func;
=09=09=09=09internal GTreeModelInterfaceFinalizeFuncDelegate finalize_func;
=09=09=09=09internal IntPtr iface_data;
=09=09=09}

=09=09[DllImport("libgtk-win32-2.0-0.dll")]
=09=09static extern IntPtr gtk_tree_model_get_type ();

=09=09[DllImport("libgobject-2.0-0.dll")]
=09=09static extern void g_type_add_interface_static (IntPtr instance_type,
=09=09=09=09=09=09=09=09=09=09=09=09=09=09=09IntPtr interface_type,
=09=09=09=09=09=09=09=09=09=09=09=09=09=09=09ref GInterfaceInfo info);

=09=09internal static GLib.GType ManagedTreeModelGType;
=09=09internal static GInterfaceInfo ManagedTreeModelInterfaceInfo;
=09=09internal static TreeModelInterface ManagedTreeModelInterfaceStruct;

=09=09internal static GLib.GType ManagedTreeModelGetType () {
=09=09=09if (ManagedTreeModelGType.Val =3D=3D IntPtr.Zero) {
=09=09=09=09/* register this type */
=09=09=09=09ManagedTreeModelGType =3D GLib.Object.RegisterGType (typeof(Man=
agedTreeModel));

=09=09=09=09/* Add the TreeModel interface */
=09=09=09=09ManagedTreeModelInterfaceInfo.init_func =3D new GTreeModelInter=
faceInitFuncDelegate (tree_model_iface_init);
=09=09=09=09ManagedTreeModelInterfaceInfo.finalize_func =3D new GTreeModelI=
nterfaceFinalizeFuncDelegate (tree_model_iface_finalize);
=09=09=09=09g_type_add_interface_static (ManagedTreeModelGType.Val, gtk_tre=
e_model_get_type(), ref ManagedTreeModelInterfaceInfo);
=09=09=09}

=09=09=09return ManagedTreeModelGType;
=09=09}

=09=09// internal static void tree_model_iface_init (ref TreeModelInterface=
 iface, IntPtr data) {
=09=09internal static void tree_model_iface_init (IntPtr ifaceptr, IntPtr d=
ata) {
=09=09=09TreeModelInterface iface =3D (TreeModelInterface) Marshal.PtrToStr=
ucture (ifaceptr, typeof(TreeModelInterface));

=09=09=09iface.get_flags =3D new TreeModelGetFlagsDelegate (TreeModelGetFla=
gsImpl);
=09=09=09iface.get_n_columns =3D new TreeModelGetNColumnsDelegate (TreeMode=
lGetNColumnsImpl);
=09=09=09iface.get_column_type =3D new TreeModelGetColumnTypeDelegate (Tree=
ModelGetColumnTypeImpl);
=09=09=09iface.get_iter =3D new TreeModelGetIterDelegate (TreeModelGetIterI=
mpl);
=09=09=09iface.get_path =3D new TreeModelGetPathDelegate (TreeModelGetPathI=
mpl);
=09=09=09iface.get_value =3D new TreeModelGetValueDelegate (TreeModelGetVal=
ueImpl);
=09=09=09iface.iter_next =3D new TreeModelIterNextDelegate (TreeModelIterNe=
xtImpl);
=09=09=09iface.iter_children =3D new TreeModelIterChildrenDelegate (TreeMod=
elIterChildrenImpl);
=09=09=09iface.iter_has_child =3D new TreeModelIterHasChildDelegate (TreeMo=
delIterHasChildImpl);
=09=09=09iface.iter_n_children =3D new TreeModelIterNChildrenDelegate (Tree=
ModelIterNChildrenImpl);
=09=09=09iface.iter_nth_child =3D new TreeModelIterNthChildDelegate (TreeMo=
delIterNthChildImpl);
=09=09=09iface.iter_parent =3D new TreeModelIterParentDelegate (TreeModelIt=
erParentImpl);
=09=09=09iface.ref_node =3D new TreeModelRefNodeDelegate (TreeModelRefNodeI=
mpl);
=09=09=09iface.unref_node =3D new TreeModelUnrefNodeDelegate (TreeModelUnre=
fNodeImpl);

=09=09=09ManagedTreeModelInterfaceStruct =3D iface;
=09=09=09Marshal.StructureToPtr (iface, ifaceptr, false);
=09=09}

=09=09internal static void tree_model_iface_finalize (IntPtr ifaceptr, IntP=
tr data) {
=09=09}

=09=09internal static int TreeModelGetFlagsImpl (IntPtr tree_model) {
=09=09=09Gtk.TreeModel tm =3D (Gtk.TreeModel) GLib.Object.GetObject (tree_m=
odel, false);
=09=09=09GC.Collect();
=09=09=09return (int) tm.Flags;
=09=09}

=09=09internal static int TreeModelGetNColumnsImpl (IntPtr tree_model) {
=09=09=09Gtk.TreeModel tm =3D (Gtk.TreeModel) GLib.Object.GetObject (tree_m=
odel, false);
=09=09=09GC.Collect();
=09=09=09return tm.NColumns;
=09=09}

=09=09internal static IntPtr TreeModelGetColumnTypeImpl (IntPtr tree_model,=
 int index) {
=09=09=09Gtk.TreeModel tm =3D (Gtk.TreeModel) GLib.Object.GetObject (tree_m=
odel, false);
=09=09=09GC.Collect();
=09=09=09return tm.GetColumnType (index).Val;
=09=09}

=09=09internal static bool TreeModelGetIterImpl (IntPtr tree_model, out Tre=
eIter iter, IntPtr path) {
=09=09=09Gtk.TreeModel tm =3D (Gtk.TreeModel) GLib.Object.GetObject (tree_m=
odel, false);
=09=09=09GC.Collect();
=09=09=09return tm.GetIter (out iter, new TreePath(path));
=09=09}

=09=09internal static IntPtr /* path */ TreeModelGetPathImpl (IntPtr tree_m=
odel, /* ref TreeIter */ IntPtr iter) {
=09=09=09Gtk.TreeModel tm =3D (Gtk.TreeModel) GLib.Object.GetObject (tree_m=
odel, false);
=09=09=09GC.Collect();
=09=09=09TreePath path =3D tm.GetPath (TreeIter.New (iter));
=09=09=09if (path =3D=3D null)
=09=09=09=09return IntPtr.Zero;
=09=09=09return path.Handle;
=09=09}

=09=09internal static void TreeModelGetValueImpl (IntPtr tree_model, ref Tr=
eeIter iter, int column, ref GLib.Value value) {
=09=09=09Gtk.TreeModel tm =3D (Gtk.TreeModel) GLib.Object.GetObject (tree_m=
odel, false);
=09=09=09GC.Collect();
=09=09=09tm.GetValue (iter, column, ref value);
=09=09}

=09=09internal static bool TreeModelIterNextImpl (IntPtr tree_model, ref Tr=
eeIter iter) {
=09=09=09Gtk.TreeModel tm =3D (Gtk.TreeModel) GLib.Object.GetObject (tree_m=
odel, false);
=09=09=09GC.Collect();
=09=09=09return tm.IterNext (ref iter);
=09=09}

=09=09internal static bool TreeModelIterChildrenImpl (IntPtr tree_model, re=
f TreeIter iter, /* ref TreeIter */ IntPtr parent) {
=09=09=09Gtk.TreeModel tm =3D (Gtk.TreeModel) GLib.Object.GetObject (tree_m=
odel, false);
=09=09=09GC.Collect();
=09=09=09return tm.IterChildren (out iter, TreeIter.New (parent));
=09=09}

=09=09internal static bool TreeModelIterHasChildImpl (IntPtr tree_model, /*=
 ref TreeIter */ IntPtr iter) {
=09=09=09Gtk.TreeModel tm =3D (Gtk.TreeModel) GLib.Object.GetObject (tree_m=
odel, false);
=09=09=09GC.Collect();
=09=09=09return tm.IterHasChild (TreeIter.New (iter));
=09=09}

=09=09internal static int TreeModelIterNChildrenImpl (IntPtr tree_model, /*=
 ref TreeIter */ IntPtr iter) {
=09=09=09Gtk.TreeModel tm =3D (Gtk.TreeModel) GLib.Object.GetObject (tree_m=
odel, false);
=09=09=09GC.Collect();
=09=09=09return tm.IterNChildren (TreeIter.New (iter));
=09=09}

=09=09internal static bool TreeModelIterNthChildImpl (IntPtr tree_model, ou=
t TreeIter iter, /* ref TreeIter */ IntPtr parent, int n) {
=09=09=09Gtk.TreeModel tm =3D (Gtk.TreeModel) GLib.Object.GetObject (tree_m=
odel, false);
=09=09=09GC.Collect();
=09=09=09return tm.IterNthChild (out iter, TreeIter.New (parent), n);
=09=09}

=09=09internal static bool TreeModelIterParentImpl (IntPtr tree_model, ref =
TreeIter iter, ref TreeIter child) {
=09=09=09Gtk.TreeModel tm =3D (Gtk.TreeModel) GLib.Object.GetObject (tree_m=
odel, false);
=09=09=09GC.Collect();
=09=09=09return tm.IterParent (out iter, child);
=09=09}

=09=09internal static void TreeModelRefNodeImpl (IntPtr tree_model, ref Tre=
eIter iter) {
=09=09=09Gtk.TreeModel tm =3D (Gtk.TreeModel) GLib.Object.GetObject (tree_m=
odel, false);
=09=09=09GC.Collect();
=09=09=09tm.RefNode (iter);
=09=09}

=09=09internal static void TreeModelUnrefNodeImpl (IntPtr tree_model, ref T=
reeIter iter) {
=09=09=09Gtk.TreeModel tm =3D (Gtk.TreeModel) GLib.Object.GetObject (tree_m=
odel, false);
=09=09=09GC.Collect();
=09=09=09tm.UnrefNode (iter);
=09=09}

=09=09public ManagedTreeModel ()
=09=09=09: base (ManagedTreeModelGetType ())
=09=09{
=09=09}

=09=09public ManagedTreeModel (IntPtr handle)
=09=09=09: base (handle)
=09=09{
=09=09}

=09}

}

------=_Part_127_30261212.1085892804612
Content-Type: text/x-csharp; name="NodeStore2.cs"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="NodeStore2.cs"

// NodeStore.cs - Tree store implementation for TreeView.
//
// Author: Mike Kestner  <mkestner@ximian.com>
//
// <c> 2003 Novell, Inc.

namespace Gtk {

=09using System;
=09using System.Collections;
=09using System.Reflection;
=09using System.Runtime.InteropServices;

=09public class NodeStore : ManagedTreeModel {

=09=09class IDHashtable : Hashtable {
=09=09=09class IDComparer : IComparer {
=09=09=09=09public int Compare (object x, object y)
=09=09=09=09{
=09=09=09=09=09if ((int) x =3D=3D (int) y)
=09=09=09=09=09=09return 0;
=09=09=09=09=09else
=09=09=09=09=09=09return 1;
=09=09=09=09}
=09=09=09}

=09=09=09 class IDHashCodeProvider : IHashCodeProvider {
=09=09=09=09public int GetHashCode (object o)
=09=09=09=09{
=09=09=09=09=09return (int) o;
=09=09=09=09}
=09=09=09}

=09=09=09public IDHashtable () : base (new IDHashCodeProvider (), new IDCom=
parer ()) {}
       =09}

=09=09static int stamp =3D 0x1234;
=09=09Hashtable node_hash =3D new IDHashtable ();
=09=09PropertyInfo[] getters;
=09=09ArrayList nodes =3D new ArrayList ();

=09=09/*
=09=09 * TreeModel interface
=09=09 */

=09=09public override Gtk.TreeModelFlags Flags {
=09=09=09get {
=09=09=09=09return TreeModelFlags.ItersPersist;
=09=09=09}
=09=09}

=09=09public override int NColumns {
=09=09=09get {
=09=09=09=09return getters.Length;
=09=09=09}
=09=09}

=09=09public override System.Type ColumnType (int index) {
=09=09=09return getters[index].PropertyType;
=09=09}

=09=09public override bool GetIter (out Gtk.TreeIter iter, Gtk.TreePath pat=
h) {
=09=09=09ITreeNode node =3D GetNodeAtPath (path);
=09=09=09if (node =3D=3D null) {
=09=09=09=09iter =3D Gtk.TreeIter.Zero;
=09=09=09=09return false;
=09=09=09}

=09=09=09iter =3D IterForNode (node);
=09=09=09node_hash [node.ID] =3D node;

=09=09=09return true;
=09=09}

=09=09public override Gtk.TreePath GetPath (Gtk.TreeIter iter) {
=09=09=09if (iter.Stamp !=3D stamp)
=09=09=09=09throw new Exception ("Bad iterator stamp");

=09=09=09TreePath path =3D new TreePath ();
=09=09=09int idx =3D (int) iter.UserData1;

=09=09=09ITreeNode node =3D node_hash [idx] as ITreeNode;
=09=09=09if (node =3D=3D null) throw new Exception ("Invalid Node ID");

=09=09=09while (node.Parent !=3D null) {
=09=09=09=09idx =3D node.Parent.IndexOf (node);
=09=09=09=09if (idx < 0) throw new Exception ("Badly formed tree");
=09=09=09=09path.PrependIndex (idx);
=09=09=09=09node =3D node.Parent;
=09=09=09}

=09=09=09idx =3D Nodes.IndexOf (node);
=09=09=09if (idx < 0) throw new Exception ("Node not found in Nodes list");
=09=09=09path.PrependIndex (idx);

=09=09=09return path;
=09=09}

=09=09public override object GetValue (Gtk.TreeIter iter, int column) {
=09=09=09if (iter.Stamp !=3D stamp)
=09=09=09=09throw new Exception ("Bad iterator stamp");

=09=09=09if (getters =3D=3D null || column >=3D getters.Length)
=09=09=09=09return null;

=09=09=09int idx =3D (int) iter.UserData1;
=09=09=09ITreeNode node =3D node_hash [idx] as ITreeNode;
=09=09=09if (node =3D=3D null)
=09=09=09=09return null;

=09=09=09return getters[column].GetValue (node, null);
=09=09}

=09=09public override bool IterNext (ref Gtk.TreeIter iter) {
=09=09=09if (iter.Stamp !=3D stamp)
=09=09=09=09throw new Exception ("Bad iterator stamp");

=09=09=09int idx =3D (int) iter.UserData1;
=09=09=09ITreeNode node =3D node_hash [idx] as ITreeNode;
=09=09=09if (node =3D=3D null)
=09=09=09=09return false;

=09=09=09if (node.Parent =3D=3D null)
=09=09=09=09idx =3D Nodes.IndexOf (node);
=09=09=09else
=09=09=09=09idx =3D node.Parent.IndexOf (node);
=09=09=09
=09=09=09if (idx < 0) throw new Exception ("Node not found in Nodes list");

=09=09=09if (node.Parent =3D=3D null) {
=09=09=09=09if (++idx >=3D Nodes.Count)
=09=09=09=09=09return false;
=09=09=09=09node =3D Nodes [idx] as ITreeNode;
=09=09=09} else {
=09=09=09=09if (++idx >=3D node.Parent.ChildCount)
=09=09=09=09=09return false;
=09=09=09=09node =3D node.Parent [idx];
=09=09=09}

=09=09=09node_hash [node.ID] =3D node;
=09=09=09iter.UserData1 =3D (IntPtr) node.ID;
=09=09=09return true;
=09=09}

=09=09public override bool IterChildren (out Gtk.TreeIter iter, Gtk.TreeIte=
r parent) {
=09=09=09return IterNthChild (out iter, parent, 0);
=09=09}

=09=09public override int IterNChildren (Gtk.TreeIter iter) {
=09=09=09if (iter.Equals(Gtk.TreeIter.Zero))
=09=09=09=09return Nodes.Count;

=09=09=09ITreeNode node =3D node_hash [(int) iter.UserData1] as ITreeNode;
=09=09=09if (node =3D=3D null)
=09=09=09=09return 0;

=09=09=09return node.ChildCount;
=09=09}

=09=09public override bool IterNthChild (out Gtk.TreeIter iter, Gtk.TreeIte=
r parent, int n) {
=09=09=09int parent_idx =3D (int) parent.UserData1;
=09=09=09ITreeNode node;

=09=09=09iter =3D Gtk.TreeIter.Zero;

=09=09=09if (parent.Equals(Gtk.TreeIter.Zero)) {
=09=09=09=09if (Nodes.Count <=3D n)
=09=09=09=09=09return false;
=09=09=09=09node =3D Nodes [n] as ITreeNode;
=09=09=09} else {
=09=09=09=09node =3D node_hash [parent_idx] as ITreeNode;
=09=09=09=09if (node =3D=3D null || node.ChildCount <=3D n)
=09=09=09=09=09return false;
=09=09=09=09node =3D node [n];
=09=09=09}

=09=09=09iter =3D IterForNode (node);
=09=09=09node_hash [node.ID] =3D node;

=09=09=09return true;
=09=09}

=09=09public override bool IterParent (out Gtk.TreeIter iter, Gtk.TreeIter =
child) {
=09=09=09iter =3D Gtk.TreeIter.Zero;
=09=09=09int child_idx =3D (int) child.UserData1;
=09=09=09ITreeNode node =3D node_hash [child_idx] as ITreeNode;
=09=09=09if (node =3D=3D null || node.Parent =3D=3D null)
=09=09=09=09return false;

=09=09=09iter =3D IterForNode (node.Parent);
=09=09=09node_hash [node.Parent.ID] =3D node.Parent;

=09=09=09return true;
=09=09}

=09=09/*
=09=09 * NodeStore methods
=09=09 */

=09=09public NodeStore (Type node_type)
=09=09{
=09=09=09ScanType (node_type);
=09=09}

=09=09void ScanType (Type type)
=09=09{
=09=09=09object[] attrs =3D type.GetCustomAttributes (false);
=09=09=09int n_cols =3D 0;

=09=09=09foreach (object attr in attrs) {
=09=09=09=09switch (attr.ToString ()) {
=09=09=09=09case "Gtk.TreeNodeAttribute":
=09=09=09=09=09TreeNodeAttribute tna =3D attr as TreeNodeAttribute;
=09=09=09=09=09n_cols =3D tna.ColumnCount;
=09=09=09=09=09break;
=09=09=09=09default:
=09=09=09=09=09Console.WriteLine ("Unknown attr: " + attr);
=09=09=09=09=09break;
=09=09=09=09}
=09=09=09}

=09=09=09if (n_cols =3D=3D 0)
=09=09=09=09return;

 =09=09=09getters =3D new PropertyInfo [n_cols];

=09=09=09MemberInfo[] info =3D type.GetMembers ();
=09=09=09foreach (MemberInfo mi in info) {
=09=09=09=09PropertyInfo pi;
=09=09=09=09object[] attr_info =3D mi.GetCustomAttributes (false);
=09=09=09=09foreach (object attr in attr_info) {
=09=09=09=09=09switch (attr.ToString ()) {
=09=09=09=09=09case "Gtk.TreeNodeValueAttribute":
=09=09=09=09=09=09TreeNodeValueAttribute tnva =3D attr as TreeNodeValueAttr=
ibute;
=09=09=09=09=09=09int col =3D tnva.Column;
=09=09=09=09=09=09pi =3D mi as PropertyInfo;
=09=09=09=09=09=09getters [col] =3D pi;
=09=09=09=09=09=09break;
=09=09=09=09=09default:
=09=09=09=09=09=09Console.WriteLine ("Unknown custom attr: " + attr);
=09=09=09=09=09=09break;
=09=09=09=09=09}
=09=09=09=09}
=09=09=09}
=09=09}

=09=09private IList Nodes {
=09=09=09get {
=09=09=09=09return nodes as IList;
=09=09=09}
=09=09}

=09=09private Gtk.TreeIter IterForNode (ITreeNode node) {
=09=09=09Gtk.TreeIter result =3D new Gtk.TreeIter ();
=09=09=09result.Stamp =3D stamp;
=09=09=09result.UserData1 =3D (IntPtr) node.ID;

=09=09=09return result;
=09=09}

=09=09private ITreeNode GetNodeAtPath (TreePath path) {
=09=09=09int[] indices =3D path.Indices;

=09=09=09if (indices[0] >=3D Nodes.Count)
=09=09=09=09return null;

=09=09=09ITreeNode node =3D Nodes [indices [0]] as ITreeNode;
=09=09=09int i;
=09=09=09for (i =3D 1; i < path.Depth; i++) {
=09=09=09=09if (indices [i] >=3D node.ChildCount)
=09=09=09=09=09return null;

=09=09=09=09node =3D node [indices [i]];
=09=09=09}

=09=09=09return node;
=09=09}

=09=09public void AddNode (ITreeNode node)
=09=09{
=09=09=09nodes.Add (node);
=09=09=09node_hash [node.ID] =3D node;
=09=09=09ConnectNode (node);
=09=09=09for (int i =3D 0; i < node.ChildCount; i++)
=09=09=09=09ConnectNode (node [i]);

=09=09=09Gtk.TreeIter iter =3D IterForNode (node);
=09=09=09EmitRowInserted (GetPath (iter), iter);
=09=09}

=09=09public void RemoveNode (ITreeNode node)
=09=09{
=09=09=09int idx =3D nodes.IndexOf (node);
=09=09=09if (idx < 0)
=09=09=09=09return;

=09=09=09TreeIter iter =3D IterForNode (node);
=09=09=09TreePath path =3D GetPath (iter);

=09=09=09nodes.Remove (node);

=09=09=09EmitRowDeleted (path);
=09=09}

=09=09public ITreeNode GetNode (TreePath path) {
=09=09=09if (path =3D=3D null)
=09=09=09=09throw new ArgumentNullException ();

=09=09=09return GetNodeAtPath (path);
=09=09}

=09=09public ITreeNode GetNode (TreeIter iter) {
=09=09=09if (iter.Equals(TreeIter.Zero))
=09=09=09=09throw new ArgumentNullException ();

=09=09=09int node_idx =3D (int) iter.UserData1;
=09=09=09ITreeNode node =3D Nodes [node_idx] as ITreeNode;
=09=09=09return node;
=09=09}

=09=09/*
=09=09 * ITreeNode event handlers
=09=09 */

=09=09private void changed_cb (object o, EventArgs args)
=09=09{
=09=09=09ITreeNode node =3D o as ITreeNode;
=09=09=09TreeIter iter =3D IterForNode (node);
=09=09=09TreePath path =3D GetPath (iter);

=09=09=09EmitRowChanged (path, iter);
=09=09}

=09=09private void child_added_cb (object o, ITreeNode child)
=09=09{
=09=09=09node_hash [child.ID] =3D child;

=09=09=09TreeIter child_iter =3D IterForNode (child);
=09=09=09TreePath child_path =3D GetPath (child_iter);

=09=09=09EmitRowInserted (child_path, child_iter);
=09=09}

=09=09private void child_deleted_cb (object o, int idx)
=09=09{
=09=09=09ITreeNode node =3D o as ITreeNode;
=09=09=09TreeIter iter =3D IterForNode (node);
=09=09=09TreePath path =3D GetPath (iter);
=09=09=09TreePath child_path =3D path.Copy ();
=09=09=09child_path.AppendIndex (idx);

=09=09=09EmitRowDeleted (child_path);

=09=09=09if (node.ChildCount <=3D 0) {
=09=09=09=09node_hash [node.ID] =3D node;

=09=09=09=09EmitRowHasChildToggled (path, iter);
=09=09=09}
=09=09}

=09=09private void ConnectNode (ITreeNode node)
=09=09{
=09=09=09node.Changed +=3D new EventHandler (changed_cb);
=09=09=09node.ChildAdded +=3D new TreeNodeAddedHandler (child_added_cb);
=09=09=09node.ChildRemoved +=3D new TreeNodeRemovedHandler (child_deleted_c=
b);
=09=09}
=09}
}

------=_Part_127_30261212.1085892804612--