GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-tree-model-selection.c
1 /*
2  * gnc-tree-model-selection.c -- GtkTreeModel which supports a
3  * selectable column.
4  *
5  * Copyright (C) 2003 Jan Arne Petersen
6  * Author: Jan Arne Petersen <[email protected]>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
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
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, contact:
20  *
21  * Free Software Foundation Voice: +1-617-542-5942
22  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
23  * Boston, MA 02110-1301, USA [email protected]
24  */
25 
26 #include "config.h"
27 
28 #include <gtk/gtk.h>
29 
30 #include "gnc-tree-model-selection.h"
31 
32 static void gnc_tree_model_selection_class_init (GncTreeModelSelectionClass *klass);
33 static void gnc_tree_model_selection_init (GncTreeModelSelection *model);
34 static void gnc_tree_model_selection_finalize (GObject *object);
35 
36 static void gnc_tree_model_selection_tree_model_init (GtkTreeModelIface *iface);
37 static GtkTreeModelFlags gnc_tree_model_selection_get_flags (GtkTreeModel *tree_model);
38 static int gnc_tree_model_selection_get_n_columns (GtkTreeModel *tree_model);
39 static GType gnc_tree_model_selection_get_column_type (GtkTreeModel *tree_model,
40  int index);
41 static gboolean gnc_tree_model_selection_get_iter (GtkTreeModel *tree_model,
42  GtkTreeIter *iter,
43  GtkTreePath *path);
44 static GtkTreePath *gnc_tree_model_selection_get_path (GtkTreeModel *tree_model,
45  GtkTreeIter *iter);
46 static void gnc_tree_model_selection_get_value (GtkTreeModel *tree_model,
47  GtkTreeIter *iter,
48  int column,
49  GValue *value);
50 static gboolean gnc_tree_model_selection_iter_next (GtkTreeModel *tree_model,
51  GtkTreeIter *iter);
52 static gboolean gnc_tree_model_selection_iter_children (GtkTreeModel *tree_model,
53  GtkTreeIter *iter,
54  GtkTreeIter *parent);
55 static gboolean gnc_tree_model_selection_iter_has_child (GtkTreeModel *tree_model,
56  GtkTreeIter *iter);
57 static int gnc_tree_model_selection_iter_n_children (GtkTreeModel *tree_model,
58  GtkTreeIter *iter);
59 static gboolean gnc_tree_model_selection_iter_nth_child (GtkTreeModel *tree_model,
60  GtkTreeIter *iter,
61  GtkTreeIter *parent,
62  int n);
63 static gboolean gnc_tree_model_selection_iter_parent (GtkTreeModel *tree_model,
64  GtkTreeIter *iter,
65  GtkTreeIter *child);
66 
67 static void gnc_tree_model_selection_row_changed (GtkTreeModel *tree_model,
68  GtkTreePath *path,
69  GtkTreeIter *iter,
70  GncTreeModelSelection *selection_model);
71 static void gnc_tree_model_selection_row_inserted (GtkTreeModel *tree_model,
72  GtkTreePath *path,
73  GtkTreeIter *iter,
74  GncTreeModelSelection *selection_model);
75 static void gnc_tree_model_selection_row_has_child_toggled (GtkTreeModel *tree_model,
76  GtkTreePath *path,
77  GtkTreeIter *iter,
78  GncTreeModelSelection *selection_model);
79 static void gnc_tree_model_selection_row_deleted (GtkTreeModel *tree_model,
80  GtkTreePath *path,
81  GncTreeModelSelection *selection_model);
82 static void gnc_tree_model_selection_rows_reordered (GtkTreeModel *tree_model,
83  GtkTreePath *path,
84  GtkTreeIter *iter,
85  gint *new_order,
86  GncTreeModelSelection *selection_model);
87 
88 static void gnc_tree_model_selection_toggled (GtkCellRendererToggle *toggle,
89  gchar *path,
90  GncTreeModelSelection *model);
91 
93 {
94  GtkTreeModel *child_model;
95 
96  GHashTable *selections;
98 
99 #define GNC_TREE_MODEL_SELECTION_GET_PRIVATE(o) \
100  (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_TREE_MODEL_SELECTION, GncTreeModelSelectionPrivate))
101 
102 static GObjectClass *parent_class = NULL;
103 
104 GType
105 gnc_tree_model_selection_get_type (void)
106 {
107  static GType gnc_tree_model_selection_type = 0;
108 
109  if (gnc_tree_model_selection_type == 0)
110  {
111  static const GTypeInfo our_info =
112  {
114  NULL,
115  NULL,
116  (GClassInitFunc) gnc_tree_model_selection_class_init,
117  NULL,
118  NULL,
119  sizeof (GncTreeModelSelection),
120  0,
121  (GInstanceInitFunc) gnc_tree_model_selection_init
122  };
123 
124  static const GInterfaceInfo tree_model_info =
125  {
126  (GInterfaceInitFunc) gnc_tree_model_selection_tree_model_init,
127  NULL,
128  NULL
129  };
130 
131  gnc_tree_model_selection_type = g_type_register_static (G_TYPE_OBJECT,
132  "GncTreeModelSelection",
133  &our_info, 0);
134 
135  g_type_add_interface_static (gnc_tree_model_selection_type,
136  GTK_TYPE_TREE_MODEL,
137  &tree_model_info);
138  }
139 
140  return gnc_tree_model_selection_type;
141 }
142 
143 static void
144 gnc_tree_model_selection_class_init (GncTreeModelSelectionClass *klass)
145 {
146  GObjectClass *object_class = G_OBJECT_CLASS (klass);
147 
148  parent_class = g_type_class_peek_parent (klass);
149 
150  object_class->finalize = gnc_tree_model_selection_finalize;
151 
152  g_type_class_add_private(klass, sizeof(GncTreeModelSelectionPrivate));
153 }
154 
155 static void
156 gnc_tree_model_selection_init (GncTreeModelSelection *model)
157 {
159 
160  while (model->stamp == 0)
161  {
162  model->stamp = g_random_int ();
163  }
164 
165  priv = GNC_TREE_MODEL_SELECTION_GET_PRIVATE(model);
166  priv->selections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
167 }
168 
169 static void
170 gnc_tree_model_selection_finalize (GObject *object)
171 {
172  GncTreeModelSelection *model;
174 
175  g_return_if_fail (object != NULL);
176  g_return_if_fail (GNC_IS_TREE_MODEL_SELECTION (object));
177 
178  model = GNC_TREE_MODEL_SELECTION (object);
179  priv = GNC_TREE_MODEL_SELECTION_GET_PRIVATE(model);
180 
181  g_object_unref (priv->child_model);
182  g_hash_table_destroy (priv->selections);
183 
184  G_OBJECT_CLASS (parent_class)->finalize (object);
185 }
186 
187 GtkTreeModel *
188 gnc_tree_model_selection_new (GtkTreeModel *child_model)
189 {
190  GncTreeModelSelection *model;
192 
193  model = g_object_new (GNC_TYPE_TREE_MODEL_SELECTION, NULL);
194  priv = GNC_TREE_MODEL_SELECTION_GET_PRIVATE(model);
195 
196  priv->child_model = child_model;
197  g_object_ref (child_model);
198  g_signal_connect (G_OBJECT (child_model), "row_changed",
199  G_CALLBACK (gnc_tree_model_selection_row_changed), model);
200  g_signal_connect (G_OBJECT (child_model), "row_inserted",
201  G_CALLBACK (gnc_tree_model_selection_row_inserted), model);
202  g_signal_connect (G_OBJECT (child_model), "row_has_child_toggled",
203  G_CALLBACK (gnc_tree_model_selection_row_has_child_toggled), model);
204  g_signal_connect (G_OBJECT (child_model), "row_deleted",
205  G_CALLBACK (gnc_tree_model_selection_row_deleted), model);
206  g_signal_connect (G_OBJECT (child_model), "rows_reordered",
207  G_CALLBACK (gnc_tree_model_selection_rows_reordered), model);
208 
209  return GTK_TREE_MODEL (model);
210 }
211 
212 void
213 gnc_tree_model_selection_convert_child_iter_to_iter (GncTreeModelSelection *model,
214  GtkTreeIter *selection_iter,
215  GtkTreeIter *child_iter)
216 {
217  g_return_if_fail (GNC_IS_TREE_MODEL_SELECTION (model));
218  g_return_if_fail (child_iter != NULL);
219  g_return_if_fail (selection_iter != NULL);
220 
221  selection_iter->stamp = model->stamp;
222 
223  selection_iter->user_data = gtk_tree_iter_copy (child_iter);
224 }
225 
226 void
227 gnc_tree_model_selection_convert_iter_to_child_iter (GncTreeModelSelection *model,
228  GtkTreeIter *child_iter,
229  GtkTreeIter *selection_iter)
230 {
231  g_return_if_fail (GNC_IS_TREE_MODEL_SELECTION (model));
232  g_return_if_fail (selection_iter != NULL);
233  g_return_if_fail (GNC_TREE_MODEL_SELECTION (model)->stamp == selection_iter->stamp);
234  g_return_if_fail (selection_iter->user_data != NULL);
235  g_return_if_fail (child_iter != NULL);
236 
237  child_iter->stamp = ((GtkTreeIter *) selection_iter->user_data)->stamp;
238  child_iter->user_data = ((GtkTreeIter *) selection_iter->user_data)->user_data;
239  child_iter->user_data2 = ((GtkTreeIter *) selection_iter->user_data)->user_data2;
240  child_iter->user_data3 = ((GtkTreeIter *) selection_iter->user_data)->user_data3;
241 }
242 
243 
244 void
245 gnc_tree_model_selection_set_selected (GncTreeModelSelection *model,
246  GtkTreeIter *iter,
247  gboolean selected)
248 {
250  gchar *path_string;
251  GtkTreePath *path;
252 
253  priv = GNC_TREE_MODEL_SELECTION_GET_PRIVATE(model);
254  path_string = gtk_tree_model_get_string_from_iter (GTK_TREE_MODEL (model), iter);
255 
256  if (selected == (g_hash_table_lookup (priv->selections, path_string) != NULL))
257  {
258  g_free (path_string);
259  return;
260  }
261 
262  if (selected)
263  {
264  g_hash_table_insert (priv->selections, g_strdup (path_string), GINT_TO_POINTER (1));
265  }
266  else
267  {
268  g_hash_table_remove (priv->selections, path_string);
269  }
270 
271  path = gtk_tree_path_new_from_string (path_string);
272  gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, iter);
273  gtk_tree_path_free (path);
274 
275  g_free (path_string);
276 }
277 
278 static void
279 gnc_tree_model_selection_tree_model_init (GtkTreeModelIface *iface)
280 {
281  iface->get_flags = gnc_tree_model_selection_get_flags;
282  iface->get_n_columns = gnc_tree_model_selection_get_n_columns;
283  iface->get_column_type = gnc_tree_model_selection_get_column_type;
284  iface->get_iter = gnc_tree_model_selection_get_iter;
285  iface->get_path = gnc_tree_model_selection_get_path;
286  iface->get_value = gnc_tree_model_selection_get_value;
287  iface->iter_next = gnc_tree_model_selection_iter_next;
288  iface->iter_children = gnc_tree_model_selection_iter_children;
289  iface->iter_has_child = gnc_tree_model_selection_iter_has_child;
290  iface->iter_n_children = gnc_tree_model_selection_iter_n_children;
291  iface->iter_nth_child = gnc_tree_model_selection_iter_nth_child;
292  iface->iter_parent = gnc_tree_model_selection_iter_parent;
293 }
294 
295 static GtkTreeModelFlags
296 gnc_tree_model_selection_get_flags (GtkTreeModel *tree_model)
297 {
298  GncTreeModelSelection *model;
300 
301  g_return_val_if_fail (GNC_IS_TREE_MODEL_SELECTION (tree_model), 0);
302 
303  model = GNC_TREE_MODEL_SELECTION (tree_model);
304  priv = GNC_TREE_MODEL_SELECTION_GET_PRIVATE(model);
305 
306  return gtk_tree_model_get_flags (priv->child_model);
307 }
308 
309 static int
310 gnc_tree_model_selection_get_n_columns (GtkTreeModel *tree_model)
311 {
312  GncTreeModelSelection *model;
314 
315  g_return_val_if_fail (GNC_IS_TREE_MODEL_SELECTION (tree_model), 0);
316 
317  model = GNC_TREE_MODEL_SELECTION (tree_model);
318  priv = GNC_TREE_MODEL_SELECTION_GET_PRIVATE(model);
319 
320  return gtk_tree_model_get_n_columns (priv->child_model) + 1;
321 }
322 
323 static GType
324 gnc_tree_model_selection_get_column_type (GtkTreeModel *tree_model,
325  int index)
326 {
327  GncTreeModelSelection *model;
329  gint columns = gnc_tree_model_selection_get_n_columns (tree_model);
330 
331  g_return_val_if_fail (GNC_IS_TREE_MODEL_SELECTION (tree_model), G_TYPE_INVALID);
332  g_return_val_if_fail ((index >= 0) && (index < columns), G_TYPE_INVALID);
333 
334  model = GNC_TREE_MODEL_SELECTION (tree_model);
335  priv = GNC_TREE_MODEL_SELECTION_GET_PRIVATE(model);
336 
337  if (index < columns - 1)
338  {
339  return gtk_tree_model_get_column_type (priv->child_model, index);
340  }
341  else
342  {
343  return G_TYPE_BOOLEAN;
344  }
345 }
346 
347 static gboolean
348 gnc_tree_model_selection_get_iter (GtkTreeModel *tree_model,
349  GtkTreeIter *iter,
350  GtkTreePath *path)
351 {
352  GncTreeModelSelection *model;
354  GtkTreeIter child_iter;
355 
356  g_return_val_if_fail (GNC_IS_TREE_MODEL_SELECTION (tree_model), FALSE);
357 
358  model = GNC_TREE_MODEL_SELECTION (tree_model);
359  priv = GNC_TREE_MODEL_SELECTION_GET_PRIVATE(model);
360 
361  if (!gtk_tree_model_get_iter (priv->child_model, &child_iter, path))
362  {
363  return FALSE;
364  }
365 
366  gnc_tree_model_selection_convert_child_iter_to_iter (model, iter, &child_iter);
367 
368  return TRUE;
369 }
370 
371 static GtkTreePath *
372 gnc_tree_model_selection_get_path (GtkTreeModel *tree_model,
373  GtkTreeIter *iter)
374 {
375  GncTreeModelSelection *model;
377  GtkTreeIter child_iter;
378 
379  g_return_val_if_fail (GNC_IS_TREE_MODEL_SELECTION (tree_model), NULL);
380  g_return_val_if_fail (iter != NULL, NULL);
381  g_return_val_if_fail (iter->stamp == GNC_TREE_MODEL_SELECTION (tree_model)->stamp, NULL);
382 
383  model = GNC_TREE_MODEL_SELECTION (tree_model);
384  priv = GNC_TREE_MODEL_SELECTION_GET_PRIVATE(model);
385 
386  gnc_tree_model_selection_convert_iter_to_child_iter (model, &child_iter, iter);
387 
388  return gtk_tree_model_get_path (priv->child_model, &child_iter);
389 }
390 
391 static void
392 gnc_tree_model_selection_get_value (GtkTreeModel *tree_model,
393  GtkTreeIter *iter,
394  int column,
395  GValue *value)
396 {
397  gint columns = gnc_tree_model_selection_get_n_columns (tree_model);
398  GncTreeModelSelection *model;
400  GtkTreeIter child_iter;
401  gchar *path;
402 
403  g_return_if_fail (GNC_IS_TREE_MODEL_SELECTION (tree_model));
404  g_return_if_fail ((column >= 0) && (column < columns));
405  g_return_if_fail (iter != NULL);
406  g_return_if_fail (iter->stamp == GNC_TREE_MODEL_SELECTION (tree_model)->stamp);
407 
408  model = GNC_TREE_MODEL_SELECTION (tree_model);
409  priv = GNC_TREE_MODEL_SELECTION_GET_PRIVATE(model);
410 
411  gnc_tree_model_selection_convert_iter_to_child_iter (model, &child_iter, iter);
412 
413  if (column < columns - 1)
414  {
415  gtk_tree_model_get_value (priv->child_model, &child_iter, column, value);
416  }
417  else
418  {
419  g_value_init (value, G_TYPE_BOOLEAN);
420 
421  path = gtk_tree_model_get_string_from_iter (priv->child_model, &child_iter);
422  g_value_set_boolean (value, g_hash_table_lookup (priv->selections, path) != NULL);
423  g_free (path);
424  }
425 }
426 
427 static gboolean
428 gnc_tree_model_selection_iter_next (GtkTreeModel *tree_model,
429  GtkTreeIter *iter)
430 {
431  GncTreeModelSelection *model;
433  GtkTreeIter child_iter;
434 
435  g_return_val_if_fail (GNC_IS_TREE_MODEL_SELECTION (tree_model), FALSE);
436  g_return_val_if_fail (iter != NULL, FALSE);
437  g_return_val_if_fail (iter->stamp == GNC_TREE_MODEL_SELECTION (tree_model)->stamp, FALSE);
438 
439  model = GNC_TREE_MODEL_SELECTION (tree_model);
440  priv = GNC_TREE_MODEL_SELECTION_GET_PRIVATE(model);
441 
442  gnc_tree_model_selection_convert_iter_to_child_iter (model, &child_iter, iter);
443 
444  if (!gtk_tree_model_iter_next (priv->child_model, &child_iter))
445  {
446  return FALSE;
447  }
448  else
449  {
450  gnc_tree_model_selection_convert_child_iter_to_iter (model, iter, &child_iter);
451 
452  return TRUE;
453  }
454 }
455 
456 static gboolean
457 gnc_tree_model_selection_iter_children (GtkTreeModel *tree_model,
458  GtkTreeIter *iter,
459  GtkTreeIter *parent)
460 {
461  GncTreeModelSelection *model;
463  GtkTreeIter child_iter;
464  GtkTreeIter child_parent;
465 
466  g_return_val_if_fail (GNC_IS_TREE_MODEL_SELECTION (tree_model), FALSE);
467 
468  model = GNC_TREE_MODEL_SELECTION (tree_model);
469  priv = GNC_TREE_MODEL_SELECTION_GET_PRIVATE(model);
470 
471  if (parent == NULL)
472  {
473  if (!gtk_tree_model_iter_children (priv->child_model, &child_iter, NULL))
474  return FALSE;
475  }
476  else
477  {
478  g_return_val_if_fail (parent != NULL, FALSE);
479  g_return_val_if_fail (parent->stamp == model->stamp, FALSE);
480 
481  gnc_tree_model_selection_convert_iter_to_child_iter (model, &child_parent, parent);
482 
483  if (!gtk_tree_model_iter_children (priv->child_model, &child_iter, &child_parent))
484  return FALSE;
485  }
486 
487  gnc_tree_model_selection_convert_child_iter_to_iter (model, iter, &child_iter);
488 
489  return TRUE;
490 }
491 
492 static gboolean
493 gnc_tree_model_selection_iter_has_child (GtkTreeModel *tree_model,
494  GtkTreeIter *iter)
495 {
496  GncTreeModelSelection *model;
498  GtkTreeIter child_iter;
499 
500  g_return_val_if_fail (GNC_IS_TREE_MODEL_SELECTION (tree_model), FALSE);
501  g_return_val_if_fail (iter != NULL, FALSE);
502  g_return_val_if_fail (iter->stamp == GNC_TREE_MODEL_SELECTION (tree_model)->stamp, FALSE);
503 
504  model = GNC_TREE_MODEL_SELECTION (tree_model);
505  priv = GNC_TREE_MODEL_SELECTION_GET_PRIVATE(model);
506 
507  gnc_tree_model_selection_convert_iter_to_child_iter (model, &child_iter, iter);
508 
509  return gtk_tree_model_iter_has_child (priv->child_model, &child_iter);
510 }
511 
512 static int
513 gnc_tree_model_selection_iter_n_children (GtkTreeModel *tree_model,
514  GtkTreeIter *iter)
515 {
516  GncTreeModelSelection *model;
518  GtkTreeIter child_iter;
519 
520  g_return_val_if_fail (GNC_IS_TREE_MODEL_SELECTION (tree_model), 0);
521 
522  model = GNC_TREE_MODEL_SELECTION (tree_model);
523  priv = GNC_TREE_MODEL_SELECTION_GET_PRIVATE(model);
524 
525  if (iter == NULL)
526  {
527  return gtk_tree_model_iter_n_children (priv->child_model, NULL);
528  }
529  else
530  {
531  g_return_val_if_fail (iter != NULL, 0);
532  g_return_val_if_fail (iter->stamp == model->stamp, 0);
533 
534  gnc_tree_model_selection_convert_iter_to_child_iter (model, &child_iter, iter);
535 
536  return gtk_tree_model_iter_n_children (priv->child_model, &child_iter);
537  }
538 }
539 
540 static gboolean
541 gnc_tree_model_selection_iter_nth_child (GtkTreeModel *tree_model,
542  GtkTreeIter *iter,
543  GtkTreeIter *parent,
544  int n)
545 {
546  GncTreeModelSelection *model;
548  GtkTreeIter child_iter;
549  GtkTreeIter child_parent;
550 
551  g_return_val_if_fail (GNC_IS_TREE_MODEL_SELECTION (tree_model), FALSE);
552 
553  model = GNC_TREE_MODEL_SELECTION (tree_model);
554  priv = GNC_TREE_MODEL_SELECTION_GET_PRIVATE(model);
555 
556  if (parent == NULL)
557  {
558  if (!gtk_tree_model_iter_nth_child (priv->child_model, &child_iter, NULL, n))
559  return FALSE;
560  }
561  else
562  {
563  g_return_val_if_fail (iter != NULL, FALSE);
564  g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
565 
566  gnc_tree_model_selection_convert_iter_to_child_iter (model, &child_parent, parent);
567 
568  if (!gtk_tree_model_iter_nth_child (priv->child_model, &child_iter, &child_parent, n))
569  return FALSE;
570  }
571 
572  gnc_tree_model_selection_convert_child_iter_to_iter (model, iter, &child_iter);
573 
574  return TRUE;
575 }
576 
577 static gboolean
578 gnc_tree_model_selection_iter_parent (GtkTreeModel *tree_model,
579  GtkTreeIter *iter,
580  GtkTreeIter *child)
581 {
582  GncTreeModelSelection *model;
584  GtkTreeIter child_child;
585  GtkTreeIter child_iter;
586 
587  g_return_val_if_fail (GNC_IS_TREE_MODEL_SELECTION (tree_model), FALSE);
588  g_return_val_if_fail (child != NULL, FALSE);
589  g_return_val_if_fail (child->stamp == GNC_TREE_MODEL_SELECTION (tree_model)->stamp, FALSE);
590 
591  model = GNC_TREE_MODEL_SELECTION (tree_model);
592  priv = GNC_TREE_MODEL_SELECTION_GET_PRIVATE(model);
593 
594  gnc_tree_model_selection_convert_iter_to_child_iter (model, &child_child, child);
595 
596  if (!gtk_tree_model_iter_parent (priv->child_model, &child_iter, &child_child))
597  {
598  return FALSE;
599  }
600  else
601  {
602  gnc_tree_model_selection_convert_child_iter_to_iter (model, iter, &child_iter);
603 
604  return TRUE;
605  }
606 }
607 
608 static void
609 gnc_tree_model_selection_row_changed (GtkTreeModel *tree_model,
610  GtkTreePath *path,
611  GtkTreeIter *iter,
612  GncTreeModelSelection *selection_model)
613 {
614  GtkTreeIter selection_iter;
615 
616  gnc_tree_model_selection_convert_child_iter_to_iter (selection_model, &selection_iter, iter);
617 
618  gtk_tree_model_row_changed (GTK_TREE_MODEL (selection_model), path, &selection_iter);
619 }
620 
621 static void
622 gnc_tree_model_selection_row_inserted (GtkTreeModel *tree_model,
623  GtkTreePath *path,
624  GtkTreeIter *iter,
625  GncTreeModelSelection *selection_model)
626 {
627  GtkTreeIter selection_iter;
628 
629  gnc_tree_model_selection_convert_child_iter_to_iter (selection_model, &selection_iter, iter);
630 
631  gtk_tree_model_row_inserted (GTK_TREE_MODEL (selection_model), path, &selection_iter);
632 }
633 
634 static void
635 gnc_tree_model_selection_row_has_child_toggled (GtkTreeModel *tree_model,
636  GtkTreePath *path,
637  GtkTreeIter *iter,
638  GncTreeModelSelection *selection_model)
639 {
640  GtkTreeIter selection_iter;
641 
642  gnc_tree_model_selection_convert_child_iter_to_iter (selection_model, &selection_iter, iter);
643 
644  gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (selection_model), path, &selection_iter);
645 }
646 
647 static void
648 gnc_tree_model_selection_row_deleted (GtkTreeModel *tree_model,
649  GtkTreePath *path,
650  GncTreeModelSelection *selection_model)
651 {
652  gtk_tree_model_row_deleted (GTK_TREE_MODEL (selection_model), path);
653 }
654 
655 static void
656 gnc_tree_model_selection_rows_reordered (GtkTreeModel *tree_model,
657  GtkTreePath *path,
658  GtkTreeIter *iter,
659  gint *new_order,
660  GncTreeModelSelection *selection_model)
661 {
662  GtkTreeIter selection_iter;
663 
664  gnc_tree_model_selection_convert_child_iter_to_iter (selection_model, &selection_iter, iter);
665 
666  gtk_tree_model_rows_reordered (GTK_TREE_MODEL (selection_model), path, &selection_iter, new_order);
667 }
668 
669 static void
670 gnc_tree_model_selection_toggled (GtkCellRendererToggle *toggle,
671  gchar *path,
672  GncTreeModelSelection *model)
673 {
674  GtkTreeIter iter;
675 
676  if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (model), &iter, path))
677  {
678  gnc_tree_model_selection_set_selected (model, &iter, !gtk_cell_renderer_toggle_get_active (toggle));
679  }
680 }