1 // Gtk.TreeStore.cs - Gtk TreeStore class customizations 2 // 3 // Authors: Kristian Rietveld <kris@gtk.org> 4 // Mike Kestner <mkestner@ximian.com> 5 // 6 // Copyright (c) 2002 Kristian Rietveld 7 // Copyright (c) 2004 Novell, Inc. 8 // 9 // This program is free software; you can redistribute it and/or 10 // modify it under the terms of version 2 of the Lesser GNU General 11 // Public License as published by the Free Software Foundation. 12 // 13 // This program is distributed in the hope that it will be useful, 14 // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 // Lesser General Public License for more details. 17 // 18 // You should have received a copy of the GNU Lesser General Public 19 // License along with this program; if not, write to the 20 // Free Software Foundation, Inc., 59 Temple Place - Suite 330, 21 // Boston, MA 02111-1307, USA. 22 23 namespace Gtk { 24 25 using System; 26 using System.Runtime.InteropServices; 27 28 public partial class TreeStore { 29 30 [DllImport (Global.GtkNativeDll, CallingConvention = CallingConvention.Cdecl)] gtk_tree_store_append(IntPtr raw, out TreeIter iter, ref TreeIter parent)31 static extern void gtk_tree_store_append (IntPtr raw, out TreeIter iter, ref TreeIter parent); 32 33 [DllImport (Global.GtkNativeDll, CallingConvention = CallingConvention.Cdecl)] gtk_tree_store_append(IntPtr raw, out TreeIter iter, IntPtr parent)34 static extern void gtk_tree_store_append (IntPtr raw, out TreeIter iter, IntPtr parent); 35 AppendNode()36 public TreeIter AppendNode () 37 { 38 TreeIter iter; 39 gtk_tree_store_append (Handle, out iter, IntPtr.Zero); 40 return iter; 41 } 42 AppendNode(TreeIter parent)43 public TreeIter AppendNode (TreeIter parent) 44 { 45 TreeIter iter; 46 gtk_tree_store_append (Handle, out iter, ref parent); 47 return iter; 48 } 49 50 [DllImport (Global.GtkNativeDll, CallingConvention = CallingConvention.Cdecl)] gtk_tree_store_insert(IntPtr raw, out TreeIter iter, ref TreeIter parent, int position)51 static extern void gtk_tree_store_insert (IntPtr raw, out TreeIter iter, ref TreeIter parent, int position); 52 53 [DllImport (Global.GtkNativeDll, CallingConvention = CallingConvention.Cdecl)] gtk_tree_store_insert(IntPtr raw, out TreeIter iter, IntPtr parent, int position)54 static extern void gtk_tree_store_insert (IntPtr raw, out TreeIter iter, IntPtr parent, int position); 55 InsertNode(TreeIter parent, int position)56 public TreeIter InsertNode (TreeIter parent, int position) 57 { 58 TreeIter iter; 59 gtk_tree_store_insert (Handle, out iter, ref parent, position); 60 return iter; 61 } 62 InsertNode(int position)63 public TreeIter InsertNode (int position) 64 { 65 TreeIter iter; 66 gtk_tree_store_insert (Handle, out iter, IntPtr.Zero, position); 67 return iter; 68 } 69 70 [DllImport (Global.GtkNativeDll, CallingConvention = CallingConvention.Cdecl)] gtk_tree_store_prepend(IntPtr raw, out TreeIter iter, ref TreeIter parent)71 static extern void gtk_tree_store_prepend (IntPtr raw, out TreeIter iter, ref TreeIter parent); 72 73 [DllImport (Global.GtkNativeDll, CallingConvention = CallingConvention.Cdecl)] gtk_tree_store_prepend(IntPtr raw, out TreeIter iter, IntPtr parent)74 static extern void gtk_tree_store_prepend (IntPtr raw, out TreeIter iter, IntPtr parent); 75 PrependNode(TreeIter parent)76 public TreeIter PrependNode (TreeIter parent) 77 { 78 TreeIter iter; 79 gtk_tree_store_prepend (Handle, out iter, ref parent); 80 return iter; 81 } 82 PrependNode()83 public TreeIter PrependNode () 84 { 85 TreeIter iter; 86 gtk_tree_store_prepend (Handle, out iter, IntPtr.Zero); 87 return iter; 88 } 89 90 [DllImport (Global.GtkNativeDll, CallingConvention = CallingConvention.Cdecl)] gtk_tree_store_insert_before(IntPtr raw, out TreeIter iter, ref TreeIter parent, ref TreeIter sibling)91 static extern void gtk_tree_store_insert_before (IntPtr raw, out TreeIter iter, ref TreeIter parent, ref TreeIter sibling); 92 93 [DllImport (Global.GtkNativeDll, CallingConvention = CallingConvention.Cdecl)] gtk_tree_store_insert_before(IntPtr raw, out TreeIter iter, IntPtr parent, ref TreeIter sibling)94 static extern void gtk_tree_store_insert_before (IntPtr raw, out TreeIter iter, IntPtr parent, ref TreeIter sibling); 95 InsertNodeBefore(TreeIter sibling)96 public TreeIter InsertNodeBefore (TreeIter sibling) 97 { 98 TreeIter iter; 99 gtk_tree_store_insert_before (Handle, out iter, IntPtr.Zero, ref sibling); 100 return iter; 101 } 102 InsertNodeBefore(TreeIter parent, TreeIter sibling)103 public TreeIter InsertNodeBefore (TreeIter parent, TreeIter sibling) 104 { 105 TreeIter iter; 106 gtk_tree_store_insert_before (Handle, out iter, ref parent, ref sibling); 107 return iter; 108 } 109 110 [DllImport (Global.GtkNativeDll, CallingConvention = CallingConvention.Cdecl)] gtk_tree_store_insert_after(IntPtr raw, out TreeIter iter, ref TreeIter parent, ref TreeIter sibling)111 static extern void gtk_tree_store_insert_after (IntPtr raw, out TreeIter iter, ref TreeIter parent, ref TreeIter sibling); 112 113 [DllImport (Global.GtkNativeDll, CallingConvention = CallingConvention.Cdecl)] gtk_tree_store_insert_after(IntPtr raw, out TreeIter iter, IntPtr parent, ref TreeIter sibling)114 static extern void gtk_tree_store_insert_after (IntPtr raw, out TreeIter iter, IntPtr parent, ref TreeIter sibling); 115 InsertNodeAfter(TreeIter sibling)116 public TreeIter InsertNodeAfter (TreeIter sibling) 117 { 118 TreeIter iter; 119 gtk_tree_store_insert_after (Handle, out iter, IntPtr.Zero, ref sibling); 120 return iter; 121 } 122 InsertNodeAfter(TreeIter parent, TreeIter sibling)123 public TreeIter InsertNodeAfter (TreeIter parent, TreeIter sibling) 124 { 125 TreeIter iter; 126 gtk_tree_store_insert_after (Handle, out iter, ref parent, ref sibling); 127 return iter; 128 } 129 130 [DllImport (Global.GtkNativeDll, CallingConvention = CallingConvention.Cdecl)] gtk_tree_model_iter_children(IntPtr raw, out Gtk.TreeIter iter, IntPtr parent)131 static extern bool gtk_tree_model_iter_children (IntPtr raw, out Gtk.TreeIter iter, IntPtr parent); IterChildren(out Gtk.TreeIter iter)132 public bool IterChildren (out Gtk.TreeIter iter) { 133 bool raw_ret = gtk_tree_model_iter_children (Handle, out iter, IntPtr.Zero); 134 bool ret = raw_ret; 135 return ret; 136 } 137 IterNChildren()138 public int IterNChildren () { 139 int raw_ret = gtk_tree_model_iter_n_children (Handle, IntPtr.Zero); 140 int ret = raw_ret; 141 return ret; 142 } 143 144 [DllImport (Global.GtkNativeDll, CallingConvention = CallingConvention.Cdecl)] gtk_tree_model_iter_nth_child(IntPtr raw, out Gtk.TreeIter iter, IntPtr parent, int n)145 static extern bool gtk_tree_model_iter_nth_child (IntPtr raw, out Gtk.TreeIter iter, IntPtr parent, int n); IterNthChild(out Gtk.TreeIter iter, int n)146 public bool IterNthChild (out Gtk.TreeIter iter, int n) { 147 bool raw_ret = gtk_tree_model_iter_nth_child (Handle, out iter, IntPtr.Zero, n); 148 bool ret = raw_ret; 149 return ret; 150 } 151 SetValue(Gtk.TreeIter iter, int column, bool value)152 public void SetValue (Gtk.TreeIter iter, int column, bool value) 153 { 154 GLib.Value val = new GLib.Value (value); 155 SetValue (iter, column, val); 156 val.Dispose (); 157 } 158 SetValue(Gtk.TreeIter iter, int column, double value)159 public void SetValue (Gtk.TreeIter iter, int column, double value) 160 { 161 GLib.Value val = new GLib.Value (value); 162 SetValue (iter, column, val); 163 val.Dispose (); 164 } 165 SetValue(Gtk.TreeIter iter, int column, int value)166 public void SetValue (Gtk.TreeIter iter, int column, int value) 167 { 168 GLib.Value val = new GLib.Value (value); 169 SetValue (iter, column, val); 170 val.Dispose (); 171 } 172 SetValue(Gtk.TreeIter iter, int column, string value)173 public void SetValue (Gtk.TreeIter iter, int column, string value) 174 { 175 GLib.Value val = new GLib.Value (value); 176 SetValue (iter, column, val); 177 val.Dispose (); 178 } 179 SetValue(Gtk.TreeIter iter, int column, float value)180 public void SetValue (Gtk.TreeIter iter, int column, float value) 181 { 182 GLib.Value val = new GLib.Value (value); 183 SetValue (iter, column, val); 184 val.Dispose (); 185 } 186 SetValue(Gtk.TreeIter iter, int column, uint value)187 public void SetValue (Gtk.TreeIter iter, int column, uint value) 188 { 189 GLib.Value val = new GLib.Value (value); 190 SetValue (iter, column, val); 191 val.Dispose (); 192 } 193 SetValue(Gtk.TreeIter iter, int column, object value)194 public void SetValue (Gtk.TreeIter iter, int column, object value) 195 { 196 GLib.Value val = new GLib.Value (value); 197 SetValue (iter, column, val); 198 val.Dispose (); 199 } 200 _AppendValues(Gtk.TreeIter iter, Array values)201 private void _AppendValues (Gtk.TreeIter iter, Array values) { 202 int col = 0; 203 foreach (object value in values) { 204 if (value != null) 205 SetValue (iter, col, value); 206 col++; 207 } 208 } 209 AppendValues(Gtk.TreeIter parent, Array values)210 public Gtk.TreeIter AppendValues (Gtk.TreeIter parent, Array values) { 211 Gtk.TreeIter iter = AppendNode (parent); 212 _AppendValues (iter, values); 213 return iter; 214 } 215 AppendValues(Gtk.TreeIter parent, params object[] values)216 public Gtk.TreeIter AppendValues (Gtk.TreeIter parent, params object[] values) { 217 return AppendValues (parent, (Array) values); 218 } 219 AppendValues(Array values)220 public Gtk.TreeIter AppendValues (Array values) { 221 Gtk.TreeIter iter = AppendNode (); 222 _AppendValues (iter, values); 223 return iter; 224 } 225 AppendValues(params object[] values)226 public Gtk.TreeIter AppendValues (params object[] values) { 227 return AppendValues ((Array) values); 228 } 229 230 [DllImport (Global.GtkNativeDll, CallingConvention = CallingConvention.Cdecl)] gtk_tree_store_insert_with_valuesv(IntPtr raw, out TreeIter iter, IntPtr parent, int position, int[] columns, GLib.Value[] values, int n_values)231 static extern void gtk_tree_store_insert_with_valuesv(IntPtr raw, out TreeIter iter, IntPtr parent, int position, int[] columns, GLib.Value[] values, int n_values); 232 233 [DllImport (Global.GtkNativeDll, CallingConvention = CallingConvention.Cdecl)] gtk_tree_store_insert_with_valuesv(IntPtr raw, out TreeIter iter, ref TreeIter parent, int position, int[] columns, GLib.Value[] values, int n_values)234 static extern void gtk_tree_store_insert_with_valuesv(IntPtr raw, out TreeIter iter, ref TreeIter parent, int position, int[] columns, GLib.Value[] values, int n_values); 235 InsertWithValues(int position, params object[] values)236 public TreeIter InsertWithValues (int position, params object[] values) 237 { 238 return InsertWithValues(false, TreeIter.Zero, position, values); 239 } 240 InsertWithValues(TreeIter parent, int position, params object[] values)241 public TreeIter InsertWithValues (TreeIter parent, int position, params object[] values) 242 { 243 return InsertWithValues(true, parent, position, values); 244 } 245 InsertWithValues(bool hasParent, TreeIter parent, int position, params object[] values)246 private TreeIter InsertWithValues (bool hasParent, TreeIter parent, int position, params object[] values) 247 { 248 int[] columns = new int[values.Length]; 249 GLib.Value[] vals = new GLib.Value[values.Length]; 250 int n_values = 0; 251 252 for (int i = 0; i < values.Length; i++) { 253 if (values[i] != null) { 254 columns[n_values] = i; 255 vals[n_values] = new GLib.Value (values[i]); 256 n_values++; 257 } 258 } 259 260 TreeIter iter; 261 if (hasParent) 262 gtk_tree_store_insert_with_valuesv (Handle, out iter, ref parent, position, columns, vals, n_values); 263 else 264 gtk_tree_store_insert_with_valuesv (Handle, out iter, IntPtr.Zero, position, columns, vals, n_values); 265 266 for (int i = 0; i < n_values; i++) 267 vals[i].Dispose (); 268 269 return iter; 270 } 271 272 [DllImport (Global.GtkNativeDll, CallingConvention = CallingConvention.Cdecl)] gtk_tree_store_set_valuesv(IntPtr raw, ref TreeIter iter, int[] columns, GLib.Value[] values, int n_values)273 static extern void gtk_tree_store_set_valuesv(IntPtr raw, ref TreeIter iter, int[] columns, GLib.Value[] values, int n_values); 274 SetValues(TreeIter iter, params object[] values)275 public void SetValues (TreeIter iter, params object[] values) 276 { 277 int[] columns = new int[values.Length]; 278 GLib.Value[] vals = new GLib.Value[values.Length]; 279 int n_values = 0; 280 281 for (int i = 0; i < values.Length; i++) { 282 if (values[i] != null) { 283 columns[n_values] = i; 284 vals[n_values] = new GLib.Value (values[i]); 285 n_values++; 286 } 287 } 288 289 gtk_tree_store_set_valuesv (Handle, ref iter, columns, vals, n_values); 290 291 for (int i = 0; i < n_values; i++) 292 vals[i].Dispose (); 293 } 294 TreeStore(params GLib.GType[] types)295 public TreeStore (params GLib.GType[] types) : base (IntPtr.Zero) 296 { 297 CreateNativeObject (new string [0], new GLib.Value [0]); 298 ColumnTypes = types; 299 } 300 TreeStore(params Type[] types)301 public TreeStore (params Type[] types) : base (IntPtr.Zero) 302 { 303 GLib.GType[] gtypes = new GLib.GType[types.Length]; 304 int i = 0; 305 foreach (Type type in types) { 306 gtypes[i] = (GLib.GType) type; 307 i++; 308 } 309 310 CreateNativeObject (new string [0], new GLib.Value [0]); 311 ColumnTypes = gtypes; 312 } 313 GetValue(Gtk.TreeIter iter, int column)314 public object GetValue (Gtk.TreeIter iter, int column) { 315 GLib.Value val = GLib.Value.Empty; 316 GetValue (iter, column, ref val); 317 object ret = val.Val; 318 val.Dispose (); 319 return ret; 320 } 321 322 [UnmanagedFunctionPointer (CallingConvention.Cdecl)] RowsReorderedSignalDelegate(IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr gch)323 delegate void RowsReorderedSignalDelegate (IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr gch); 324 RowsReorderedSignalCallback(IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr gch)325 static void RowsReorderedSignalCallback (IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr gch) 326 { 327 Gtk.RowsReorderedArgs args = new Gtk.RowsReorderedArgs (); 328 try { 329 GLib.Signal sig = ((GCHandle) gch).Target as GLib.Signal; 330 if (sig == null) 331 throw new Exception("Unknown signal GC handle received " + gch); 332 333 TreeStore sender = GLib.Object.GetObject (arg0) as TreeStore; 334 args.Args = new object[3]; 335 args.Args[0] = arg1 == IntPtr.Zero ? null : (Gtk.TreePath) GLib.Opaque.GetOpaque (arg1, typeof (Gtk.TreePath), false); 336 args.Args[1] = Gtk.TreeIter.New (arg2); 337 int child_cnt = arg2 == IntPtr.Zero ? sender.IterNChildren () : sender.IterNChildren ((TreeIter)args.Args[1]); 338 int[] new_order = new int [child_cnt]; 339 Marshal.Copy (arg3, new_order, 0, child_cnt); 340 args.Args[2] = new_order; 341 Gtk.RowsReorderedHandler handler = (Gtk.RowsReorderedHandler) sig.Handler; 342 handler (sender, args); 343 } catch (Exception e) { 344 GLib.ExceptionManager.RaiseUnhandledException (e, false); 345 } 346 } 347 348 [UnmanagedFunctionPointer (CallingConvention.Cdecl)] RowsReorderedVMDelegate(IntPtr tree_model, IntPtr path, IntPtr iter, IntPtr new_order)349 delegate void RowsReorderedVMDelegate (IntPtr tree_model, IntPtr path, IntPtr iter, IntPtr new_order); 350 351 static RowsReorderedVMDelegate RowsReorderedVMCallback; 352 rowsreordered_cb(IntPtr tree_model, IntPtr path_ptr, IntPtr iter_ptr, IntPtr new_order)353 static void rowsreordered_cb (IntPtr tree_model, IntPtr path_ptr, IntPtr iter_ptr, IntPtr new_order) 354 { 355 try { 356 TreeStore store = GLib.Object.GetObject (tree_model, false) as TreeStore; 357 TreePath path = GLib.Opaque.GetOpaque (path_ptr, typeof (TreePath), false) as TreePath; 358 TreeIter iter = TreeIter.New (iter_ptr); 359 int child_cnt = store.IterNChildren (iter); 360 int[] child_order = new int [child_cnt]; 361 Marshal.Copy (new_order, child_order, 0, child_cnt); 362 store.OnRowsReordered (path, iter, child_order); 363 } catch (Exception e) { 364 GLib.ExceptionManager.RaiseUnhandledException (e, true); 365 // NOTREACHED: above call doesn't return 366 throw e; 367 } 368 } 369 OverrideRowsReordered(GLib.GType gtype)370 private static void OverrideRowsReordered (GLib.GType gtype) 371 { 372 if (RowsReorderedVMCallback == null) 373 RowsReorderedVMCallback = new RowsReorderedVMDelegate (rowsreordered_cb); 374 OverrideVirtualMethod (gtype, "rows_reordered", RowsReorderedVMCallback); 375 } 376 377 [GLib.DefaultSignalHandler(Type=typeof(Gtk.TreeStore), ConnectionMethod="OverrideRowsReordered")] OnRowsReordered(Gtk.TreePath path, Gtk.TreeIter iter, int[] new_order)378 protected virtual void OnRowsReordered (Gtk.TreePath path, Gtk.TreeIter iter, int[] new_order) 379 { 380 GLib.Value ret = GLib.Value.Empty; 381 GLib.ValueArray inst_and_params = new GLib.ValueArray (4); 382 GLib.Value[] vals = new GLib.Value [4]; 383 vals [0] = new GLib.Value (this); 384 inst_and_params.Append (vals [0]); 385 vals [1] = new GLib.Value (path); 386 inst_and_params.Append (vals [1]); 387 vals [2] = new GLib.Value (iter); 388 inst_and_params.Append (vals [2]); 389 int cnt = IterNChildren (iter); 390 IntPtr new_order_ptr = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (int)) * cnt); 391 Marshal.Copy (new_order, 0, new_order_ptr, cnt); 392 vals [3] = new GLib.Value (new_order_ptr); 393 inst_and_params.Append (vals [3]); 394 g_signal_chain_from_overridden (inst_and_params.ArrayPtr, ref ret); 395 Marshal.FreeHGlobal (new_order_ptr); 396 397 foreach (GLib.Value v in vals) 398 v.Dispose (); 399 } 400 401 [GLib.Signal("rows_reordered")] 402 public event Gtk.RowsReorderedHandler RowsReordered { 403 add { 404 AddSignalHandler ("rows_reordered", value, new RowsReorderedSignalDelegate(RowsReorderedSignalCallback)); 405 } 406 remove { 407 RemoveSignalHandler ("rows_reordered", value); 408 } 409 } 410 } 411 } 412