41 #include <glib/gi18n.h>
44 #include "gnc-component-manager.h"
51 #define ITER_IS_NAMESPACE GINT_TO_POINTER(1)
52 #define ITER_IS_COMMODITY GINT_TO_POINTER(2)
53 #define ITER_IS_PRICE GINT_TO_POINTER(3)
79 #define RACE_CONDITION_SOLVED
87 static void gnc_tree_model_price_finalize (GObject *
object);
88 static void gnc_tree_model_price_dispose (GObject *
object);
90 static void gnc_tree_model_price_tree_model_init (GtkTreeModelIface *iface);
91 static guint gnc_tree_model_price_get_flags (GtkTreeModel *tree_model);
92 static int gnc_tree_model_price_get_n_columns (GtkTreeModel *tree_model);
93 static GType gnc_tree_model_price_get_column_type (GtkTreeModel *tree_model,
95 static gboolean gnc_tree_model_price_get_iter (GtkTreeModel *tree_model,
98 static GtkTreePath *gnc_tree_model_price_get_path (GtkTreeModel *tree_model,
100 static void gnc_tree_model_price_get_value (GtkTreeModel *tree_model,
104 static gboolean gnc_tree_model_price_iter_next (GtkTreeModel *tree_model,
106 static gboolean gnc_tree_model_price_iter_children (GtkTreeModel *tree_model,
108 GtkTreeIter *parent);
109 static gboolean gnc_tree_model_price_iter_has_child (GtkTreeModel *tree_model,
111 static int gnc_tree_model_price_iter_n_children (GtkTreeModel *tree_model,
113 static gboolean gnc_tree_model_price_iter_nth_child (GtkTreeModel *tree_model,
117 static gboolean gnc_tree_model_price_iter_parent (GtkTreeModel *tree_model,
120 static void gnc_tree_model_price_event_handler (
QofInstance *entity,
123 gpointer event_data);
130 gint event_handler_id;
134 #define GNC_TREE_MODEL_PRICE_GET_PRIVATE(o) \
135 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_TREE_MODEL_PRICE, GncTreeModelPricePrivate))
138 static GObjectClass *parent_class = NULL;
143 static GType gnc_tree_model_price_type = 0;
145 if (gnc_tree_model_price_type == 0)
147 static const GTypeInfo our_info =
152 (GClassInitFunc) gnc_tree_model_price_class_init,
157 (GInstanceInitFunc) gnc_tree_model_price_init
160 static const GInterfaceInfo tree_model_info =
162 (GInterfaceInitFunc) gnc_tree_model_price_tree_model_init,
167 gnc_tree_model_price_type = g_type_register_static (GNC_TYPE_TREE_MODEL,
168 GNC_TREE_MODEL_PRICE_NAME,
171 g_type_add_interface_static (gnc_tree_model_price_type,
176 return gnc_tree_model_price_type;
182 GObjectClass *o_class = G_OBJECT_CLASS (klass);
184 parent_class = g_type_class_peek_parent (klass);
186 o_class->finalize = gnc_tree_model_price_finalize;
187 o_class->dispose = gnc_tree_model_price_dispose;
197 while (model->
stamp == 0)
199 model->
stamp = g_random_int ();
202 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
203 priv->print_info = gnc_share_print_info_places(6);
207 gnc_tree_model_price_finalize (GObject *
object)
212 ENTER(
"model %p",
object);
214 g_return_if_fail (
object != NULL);
215 g_return_if_fail (GNC_IS_TREE_MODEL_PRICE (
object));
217 model = GNC_TREE_MODEL_PRICE (
object);
218 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
221 priv->price_db = NULL;
223 G_OBJECT_CLASS (parent_class)->finalize (
object);
228 gnc_tree_model_price_dispose (GObject *
object)
233 ENTER(
"model %p",
object);
234 g_return_if_fail (
object != NULL);
235 g_return_if_fail (GNC_IS_TREE_MODEL_PRICE (
object));
237 model = GNC_TREE_MODEL_PRICE (
object);
238 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
240 if (priv->event_handler_id)
243 priv->event_handler_id = 0;
246 if (G_OBJECT_CLASS (parent_class)->dispose)
247 G_OBJECT_CLASS (parent_class)->dispose (
object);
259 for ( ; item; item = g_list_next(item))
262 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
263 if (priv->price_db == price_db)
265 g_object_ref(G_OBJECT(model));
266 LEAVE(
"returning existing model %p", model);
267 return GTK_TREE_MODEL(model);
271 model = g_object_new (GNC_TYPE_TREE_MODEL_PRICE,
274 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
276 priv->price_db = price_db;
278 priv->event_handler_id =
281 return GTK_TREE_MODEL (model);
288 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
289 g_return_val_if_fail (iter != NULL, FALSE);
290 g_return_val_if_fail (iter->user_data != NULL, FALSE);
291 g_return_val_if_fail (iter->stamp == model->
stamp, FALSE);
293 return (iter->user_data == ITER_IS_NAMESPACE);
300 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
301 g_return_val_if_fail (iter != NULL, FALSE);
302 g_return_val_if_fail (iter->user_data != NULL, FALSE);
303 g_return_val_if_fail (iter->stamp == model->
stamp, FALSE);
305 return (iter->user_data == ITER_IS_COMMODITY);
312 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
313 g_return_val_if_fail (iter != NULL, FALSE);
314 g_return_val_if_fail (iter->user_data != NULL, FALSE);
315 g_return_val_if_fail (iter->stamp == model->
stamp, FALSE);
317 return (iter->user_data == ITER_IS_PRICE);
324 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), NULL);
325 g_return_val_if_fail (iter != NULL, NULL);
326 g_return_val_if_fail (iter->user_data != NULL, NULL);
327 g_return_val_if_fail (iter->stamp == model->
stamp, NULL);
329 if (iter->user_data != ITER_IS_NAMESPACE)
338 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), NULL);
339 g_return_val_if_fail (iter != NULL, NULL);
340 g_return_val_if_fail (iter->user_data != NULL, NULL);
341 g_return_val_if_fail (iter->stamp == model->
stamp, NULL);
343 if (iter->user_data != ITER_IS_COMMODITY)
352 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), NULL);
353 g_return_val_if_fail (iter != NULL, NULL);
354 g_return_val_if_fail (iter->user_data != NULL, NULL);
355 g_return_val_if_fail (iter->stamp == model->
stamp, NULL);
357 if (iter->user_data != ITER_IS_PRICE)
359 return (
GNCPrice *)iter->user_data2;
366 #define debug_path(fn, path) { \
367 gchar *path_string = gtk_tree_path_to_string(path); \
368 fn("tree path %s", path_string? path_string : "(NULL)"); \
369 g_free(path_string); \
372 #define ITER_STRING_LEN 256
381 #ifdef G_THREADS_ENABLED
382 #ifndef HAVE_GLIB_2_32
383 static GStaticPrivate gtmits_buffer_key = G_STATIC_PRIVATE_INIT;
386 string = g_static_private_get (>mits_buffer_key);
389 string = g_malloc(ITER_STRING_LEN + 1);
390 g_static_private_set (>mits_buffer_key,
string, g_free);
393 static GPrivate gtmits_buffer_key = G_PRIVATE_INIT(g_free);
396 string = g_private_get (>mits_buffer_key);
399 string = g_malloc(ITER_STRING_LEN + 1);
400 g_private_set (>mits_buffer_key,
string);
404 static char string[ITER_STRING_LEN + 1];
407 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
410 switch (GPOINTER_TO_INT(iter->user_data))
412 case GPOINTER_TO_INT(ITER_IS_NAMESPACE):
414 snprintf(
string, ITER_STRING_LEN,
415 "[stamp:%x data:%d (NAMESPACE), %p (%s), %d]",
416 iter->stamp, GPOINTER_TO_INT(iter->user_data),
418 GPOINTER_TO_INT(iter->user_data3));
421 case GPOINTER_TO_INT(ITER_IS_COMMODITY):
423 snprintf(
string, ITER_STRING_LEN,
424 "[stamp:%x data:%d (COMMODITY), %p (%s), %d]",
425 iter->stamp, GPOINTER_TO_INT(iter->user_data),
427 GPOINTER_TO_INT(iter->user_data3));
430 case GPOINTER_TO_INT(ITER_IS_PRICE):
431 price = (
GNCPrice *) iter->user_data2;
432 commodity = gnc_price_get_commodity(price);
433 snprintf(
string, ITER_STRING_LEN,
434 "[stamp:%x data:%d (PRICE), %p (%s:%s), %d]",
435 iter->stamp, GPOINTER_TO_INT(iter->user_data),
437 xaccPrintAmount (gnc_price_get_value (price), priv->print_info),
438 GPOINTER_TO_INT(iter->user_data3));
442 snprintf(
string, ITER_STRING_LEN,
443 "[stamp:%x data:%d (UNKNOWN), %p, %d]",
445 GPOINTER_TO_INT(iter->user_data),
447 GPOINTER_TO_INT(iter->user_data3));
460 gnc_tree_model_price_tree_model_init (GtkTreeModelIface *iface)
462 iface->get_flags = gnc_tree_model_price_get_flags;
463 iface->get_n_columns = gnc_tree_model_price_get_n_columns;
464 iface->get_column_type = gnc_tree_model_price_get_column_type;
465 iface->get_iter = gnc_tree_model_price_get_iter;
466 iface->get_path = gnc_tree_model_price_get_path;
467 iface->get_value = gnc_tree_model_price_get_value;
468 iface->iter_next = gnc_tree_model_price_iter_next;
469 iface->iter_children = gnc_tree_model_price_iter_children;
470 iface->iter_has_child = gnc_tree_model_price_iter_has_child;
471 iface->iter_n_children = gnc_tree_model_price_iter_n_children;
472 iface->iter_nth_child = gnc_tree_model_price_iter_nth_child;
473 iface->iter_parent = gnc_tree_model_price_iter_parent;
477 gnc_tree_model_price_get_flags (GtkTreeModel *tree_model)
483 gnc_tree_model_price_get_n_columns (GtkTreeModel *tree_model)
485 return GNC_TREE_MODEL_PRICE_NUM_COLUMNS;
489 gnc_tree_model_price_get_column_type (GtkTreeModel *tree_model,
492 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), G_TYPE_INVALID);
493 g_return_val_if_fail ((index < GNC_TREE_MODEL_PRICE_NUM_COLUMNS) && (index >= 0), G_TYPE_INVALID);
497 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
498 case GNC_TREE_MODEL_PRICE_COL_CURRENCY:
499 case GNC_TREE_MODEL_PRICE_COL_DATE:
500 case GNC_TREE_MODEL_PRICE_COL_SOURCE:
501 case GNC_TREE_MODEL_PRICE_COL_TYPE:
502 case GNC_TREE_MODEL_PRICE_COL_VALUE:
503 return G_TYPE_STRING;
504 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
505 return G_TYPE_BOOLEAN;
507 g_assert_not_reached ();
508 return G_TYPE_INVALID;
513 gnc_tree_model_price_get_iter (GtkTreeModel *tree_model,
523 GList *ns_list, *cm_list, *price_list;
526 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), FALSE);
528 depth = gtk_tree_path_get_depth (path);
529 ENTER(
"model %p, iter %p, path %p (depth %d)", tree_model, iter, path, depth);
530 debug_path(
DEBUG, path);
535 LEAVE(
"depth too small");
540 LEAVE(
"depth too big");
545 model = GNC_TREE_MODEL_PRICE (tree_model);
546 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
547 if (priv->price_db == NULL)
549 LEAVE(
"no price db");
556 i = gtk_tree_path_get_indices (path)[0];
557 name_space = g_list_nth_data (ns_list, i);
560 LEAVE(
"invalid path at namespace");
567 iter->stamp = model->
stamp;
568 iter->user_data = ITER_IS_NAMESPACE;
569 iter->user_data2 = name_space;
570 iter->user_data3 = GINT_TO_POINTER(i);
571 LEAVE(
"iter (ns) %s", iter_to_string(model, iter));
577 i = gtk_tree_path_get_indices (path)[1];
578 commodity = g_list_nth_data (cm_list, i);
581 LEAVE(
"invalid path at commodity");
588 iter->stamp = model->
stamp;
589 iter->user_data = ITER_IS_COMMODITY;
590 iter->user_data2 = commodity;
591 iter->user_data3 = GINT_TO_POINTER(i);
592 LEAVE(
"iter (cm) %s", iter_to_string(model, iter));
598 i = gtk_tree_path_get_indices (path)[2];
599 price = g_list_nth_data (price_list, i);
604 #ifdef RACE_CONDITION_SOLVED
607 LEAVE(
"invalid path at price");
613 iter->stamp = model->
stamp;
614 iter->user_data = ITER_IS_PRICE;
615 iter->user_data2 = price;
616 iter->user_data3 = GINT_TO_POINTER(i);
617 LEAVE(
"iter (pc) %s", iter_to_string(model, iter));
622 gnc_tree_model_price_get_path (GtkTreeModel *tree_model,
630 GList *ns_list, *cm_list;
633 ENTER(
"model %p, iter %p (%s)", tree_model, iter, iter_to_string(model, iter));
634 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), NULL);
635 g_return_val_if_fail (iter != NULL, NULL);
636 g_return_val_if_fail (iter->user_data != NULL, NULL);
637 g_return_val_if_fail (iter->stamp == model->
stamp, NULL);
640 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
641 if (priv->price_db == NULL)
643 LEAVE(
"no price db");
647 if (iter->user_data == ITER_IS_NAMESPACE)
651 path = gtk_tree_path_new ();
652 gtk_tree_path_append_index (path, GPOINTER_TO_INT(iter->user_data3));
653 debug_path(
LEAVE, path);
661 if (iter->user_data == ITER_IS_COMMODITY)
666 path = gtk_tree_path_new ();
667 gtk_tree_path_append_index (path, g_list_index (ns_list, name_space));
668 gtk_tree_path_append_index (path, GPOINTER_TO_INT(iter->user_data3));
669 debug_path(
LEAVE, path);
674 commodity = gnc_price_get_commodity((
GNCPrice*)iter->user_data2);
677 path = gtk_tree_path_new ();
678 gtk_tree_path_append_index (path, g_list_index (ns_list, name_space));
679 gtk_tree_path_append_index (path, g_list_index (cm_list, commodity));
680 gtk_tree_path_append_index (path, GPOINTER_TO_INT(iter->user_data3));
681 debug_path(
LEAVE, path);
686 gnc_tree_model_price_get_value (GtkTreeModel *tree_model,
697 g_return_if_fail (GNC_IS_TREE_MODEL_PRICE (model));
698 g_return_if_fail (iter != NULL);
699 #ifdef RACE_CONDITION_SOLVED
700 g_return_if_fail (iter->user_data != NULL);
702 g_return_if_fail (iter->stamp == model->
stamp);
704 if (iter->user_data == ITER_IS_NAMESPACE)
709 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
710 g_value_init (value, G_TYPE_STRING);
713 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
714 g_value_init (value, G_TYPE_BOOLEAN);
715 g_value_set_boolean (value, FALSE);
718 g_value_init (value, G_TYPE_STRING);
719 g_value_set_string (value,
"");
725 if (iter->user_data == ITER_IS_COMMODITY)
730 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
731 g_value_init (value, G_TYPE_STRING);
734 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
735 g_value_init (value, G_TYPE_BOOLEAN);
736 g_value_set_boolean (value, FALSE);
739 g_value_init (value, G_TYPE_STRING);
740 g_value_set_string (value,
"");
746 price = (
GNCPrice *)iter->user_data2;
747 #ifdef RACE_CONDITION_SOLVED
748 g_return_if_fail (price != NULL);
754 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
755 g_value_init (value, G_TYPE_STRING);
756 g_value_set_string (value,
"");
758 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
759 g_value_init (value, G_TYPE_BOOLEAN);
760 g_value_set_boolean (value, FALSE);
763 g_value_init (value, G_TYPE_STRING);
764 g_value_set_string (value,
"");
773 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
774 g_value_init (value, G_TYPE_STRING);
775 commodity = gnc_price_get_commodity (price);
778 case GNC_TREE_MODEL_PRICE_COL_CURRENCY:
779 g_value_init (value, G_TYPE_STRING);
780 commodity = gnc_price_get_currency (price);
783 case GNC_TREE_MODEL_PRICE_COL_DATE:
784 g_value_init (value, G_TYPE_STRING);
785 g_value_set_string (value,
gnc_print_date (gnc_price_get_time (price)));
787 case GNC_TREE_MODEL_PRICE_COL_SOURCE:
788 g_value_init (value, G_TYPE_STRING);
789 g_value_set_string (value, gettext (gnc_price_get_source (price)));
791 case GNC_TREE_MODEL_PRICE_COL_TYPE:
792 g_value_init (value, G_TYPE_STRING);
793 g_value_set_string (value, gnc_price_get_typestr (price));
795 case GNC_TREE_MODEL_PRICE_COL_VALUE:
796 g_value_init (value, G_TYPE_STRING);
797 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
798 g_value_set_string (value, xaccPrintAmount (gnc_price_get_value (price),
801 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
802 g_value_init (value, G_TYPE_BOOLEAN);
803 g_value_set_boolean (value, TRUE);
806 g_assert_not_reached ();
811 gnc_tree_model_price_iter_next (GtkTreeModel *tree_model,
822 ENTER(
"model %p, iter %p(%s)", tree_model, iter, iter_to_string(model, iter));
823 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
824 g_return_val_if_fail (iter != NULL, FALSE);
825 g_return_val_if_fail (iter->user_data != NULL, FALSE);
826 g_return_val_if_fail (iter->stamp == model->
stamp, FALSE);
828 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
829 if (iter->user_data == ITER_IS_NAMESPACE)
833 n = GPOINTER_TO_INT(iter->user_data3) + 1;
834 iter->user_data2 = g_list_nth_data(list, n);
835 if (iter->user_data2 == NULL)
837 LEAVE(
"no next iter");
840 iter->user_data3 = GINT_TO_POINTER(n);
841 LEAVE(
"iter %p(%s)", iter, iter_to_string(model, iter));
844 else if (iter->user_data == ITER_IS_COMMODITY)
848 n = GPOINTER_TO_INT(iter->user_data3) + 1;
849 iter->user_data2 = g_list_nth_data(list, n);
850 if (iter->user_data2 == NULL)
852 LEAVE(
"no next iter");
855 iter->user_data3 = GINT_TO_POINTER(n);
856 LEAVE(
"iter %p(%s)", iter, iter_to_string(model, iter));
859 else if (iter->user_data == ITER_IS_PRICE)
861 commodity = gnc_price_get_commodity((
GNCPrice*)iter->user_data2);
862 n = GPOINTER_TO_INT(iter->user_data3) + 1;
864 iter->user_data2 = g_list_nth_data(list, n);
866 if (iter->user_data2 == NULL)
868 LEAVE(
"no next iter");
871 iter->user_data3 = GINT_TO_POINTER(n);
872 LEAVE(
"iter %p(%s)", iter, iter_to_string(model, iter));
877 LEAVE(
"unknown iter type");
883 gnc_tree_model_price_iter_children (GtkTreeModel *tree_model,
894 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), FALSE);
896 model = GNC_TREE_MODEL_PRICE (tree_model);
897 ENTER(
"model %p, iter %p, parent %p (%s)",
898 tree_model, iter, parent, iter_to_string(model, parent));
900 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
907 LEAVE(
"no namespaces");
911 iter->stamp = model->
stamp;
912 iter->user_data = ITER_IS_NAMESPACE;
913 iter->user_data2 = g_list_nth_data(list, 0);
914 iter->user_data3 = GINT_TO_POINTER(0);
915 LEAVE(
"ns iter %p (%s)", iter, iter_to_string(model, iter));
919 if (parent->user_data == ITER_IS_NAMESPACE)
925 LEAVE(
"no commodities");
929 iter->stamp = model->
stamp;
930 iter->user_data = ITER_IS_COMMODITY;
931 iter->user_data2 = g_list_nth_data(list, 0);
932 iter->user_data3 = GINT_TO_POINTER(0);
933 LEAVE(
"cm iter %p (%s)", iter, iter_to_string(model, iter));
937 if (parent->user_data == ITER_IS_COMMODITY)
946 iter->stamp = model->
stamp;
947 iter->user_data = ITER_IS_PRICE;
948 iter->user_data2 = g_list_nth_data(list, 0);
949 iter->user_data3 = GINT_TO_POINTER(0);
951 LEAVE(
"price iter %p (%s)", iter, iter_to_string(model, iter));
960 gnc_tree_model_price_iter_has_child (GtkTreeModel *tree_model,
970 model = GNC_TREE_MODEL_PRICE (tree_model);
971 ENTER(
"model %p, iter %p (%s)", tree_model,
972 iter, iter_to_string(model, iter));
973 g_return_val_if_fail (tree_model != NULL, FALSE);
974 g_return_val_if_fail (iter != NULL, FALSE);
976 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
977 if (iter->user_data == ITER_IS_PRICE)
979 LEAVE(
"price has no children");
983 if (iter->user_data == ITER_IS_NAMESPACE)
987 LEAVE(
"%s children", list ?
"has" :
"no");
991 if (iter->user_data == ITER_IS_COMMODITY)
995 LEAVE(
"%s children", result ?
"has" :
"no");
999 LEAVE(
"no children (unknown type)");
1004 gnc_tree_model_price_iter_n_children (GtkTreeModel *tree_model,
1015 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), -1);
1017 model = GNC_TREE_MODEL_PRICE (tree_model);
1018 ENTER(
"model %p, iter %p (%s)", tree_model, iter,
1019 iter_to_string(model, iter));
1021 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
1026 LEAVE(
"ns list length %d", g_list_length(list));
1027 return g_list_length (list);
1030 if (iter->user_data == ITER_IS_NAMESPACE)
1034 LEAVE(
"cm list length %d", g_list_length(list));
1035 return g_list_length (list);
1038 if (iter->user_data == ITER_IS_COMMODITY)
1042 n = g_list_length(list);
1044 LEAVE(
"price list length %d", n);
1053 gnc_tree_model_price_iter_nth_child (GtkTreeModel *tree_model,
1055 GtkTreeIter *parent,
1065 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), FALSE);
1066 g_return_val_if_fail (iter != NULL, FALSE);
1068 model = GNC_TREE_MODEL_PRICE (tree_model);
1069 ENTER(
"model %p, iter %p, parent %p (%s), n %d",
1070 tree_model, iter, parent, iter_to_string(model, parent), n);
1072 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
1078 iter->stamp = model->
stamp;
1079 iter->user_data = ITER_IS_NAMESPACE;
1080 iter->user_data2 = g_list_nth_data(list, n);
1081 iter->user_data3 = GINT_TO_POINTER(n);
1082 LEAVE(
"ns iter %p (%s)", iter, iter_to_string(model, iter));
1083 return iter->user_data2 != NULL;
1086 if (parent->user_data == ITER_IS_NAMESPACE)
1091 iter->stamp = model->
stamp;
1092 iter->user_data = ITER_IS_COMMODITY;
1093 iter->user_data2 = g_list_nth_data(list, n);
1094 iter->user_data3 = GINT_TO_POINTER(n);
1095 LEAVE(
"cm iter %p (%s)", iter, iter_to_string(model, iter));
1096 return iter->user_data2 != NULL;
1099 if (parent->user_data == ITER_IS_COMMODITY)
1104 iter->stamp = model->
stamp;
1105 iter->user_data = ITER_IS_PRICE;
1106 iter->user_data2 = g_list_nth_data(list, n);
1107 iter->user_data3 = GINT_TO_POINTER(n);
1109 LEAVE(
"price iter %p (%s)", iter, iter_to_string(model, iter));
1110 return iter->user_data2 != NULL;
1119 gnc_tree_model_price_iter_parent (GtkTreeModel *tree_model,
1130 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), FALSE);
1131 g_return_val_if_fail (iter != NULL, FALSE);
1132 g_return_val_if_fail (child != NULL, FALSE);
1134 model = GNC_TREE_MODEL_PRICE (tree_model);
1135 ENTER(
"model %p, iter %p, child %p (%s)",
1136 tree_model, iter, child, iter_to_string(model, child));
1138 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
1139 if (child->user_data == ITER_IS_NAMESPACE)
1141 LEAVE(
"ns has no parent");
1145 if (child->user_data == ITER_IS_COMMODITY)
1151 iter->stamp = model->
stamp;
1152 iter->user_data = ITER_IS_NAMESPACE;
1153 iter->user_data2 = name_space;
1154 iter->user_data3 = GINT_TO_POINTER(g_list_index(list, name_space));
1155 LEAVE(
"ns iter %p (%s)", iter, iter_to_string(model, iter));
1159 commodity = gnc_price_get_commodity ((
GNCPrice*)child->user_data2);
1163 iter->stamp = model->
stamp;
1164 iter->user_data = ITER_IS_COMMODITY;
1165 iter->user_data2 = commodity;
1166 iter->user_data3 = GINT_TO_POINTER(g_list_index(list, commodity));
1167 LEAVE(
"cm iter %p (%s)", iter, iter_to_string(model, iter));
1190 ENTER(
"model %p, price %p, iter %p", model, price, iter);
1191 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
1192 g_return_val_if_fail ((price != NULL), FALSE);
1193 g_return_val_if_fail ((iter != NULL), FALSE);
1195 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
1196 commodity = gnc_price_get_commodity(price);
1197 if (commodity == NULL)
1199 LEAVE(
"no commodity");
1206 LEAVE(
"empty list");
1210 n = g_list_index(list, price);
1214 LEAVE(
"not in list");
1218 iter->stamp = model->
stamp;
1219 iter->user_data = ITER_IS_PRICE;
1220 iter->user_data2 = price;
1221 iter->user_data3 = GINT_TO_POINTER(n);
1223 LEAVE(
"iter %s", iter_to_string(model, iter));
1236 GtkTreeIter tree_iter;
1237 GtkTreePath *tree_path;
1239 ENTER(
"model %p, price %p", model, price);
1240 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), NULL);
1241 g_return_val_if_fail (price != NULL, NULL);
1249 tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &tree_iter);
1252 gchar *path_string = gtk_tree_path_to_string(tree_path);
1253 LEAVE(
"path (2) %s", path_string);
1254 g_free(path_string);
1277 ENTER(
"model %p, commodity %p, iter %p", model, commodity, iter);
1278 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
1279 g_return_val_if_fail ((commodity != NULL), FALSE);
1280 g_return_val_if_fail ((iter != NULL), FALSE);
1283 if (name_space == NULL)
1285 LEAVE(
"no namespace");
1292 LEAVE(
"empty list");
1296 n = g_list_index(list, commodity);
1299 LEAVE(
"not in list");
1303 iter->stamp = model->
stamp;
1304 iter->user_data = ITER_IS_COMMODITY;
1305 iter->user_data2 = commodity;
1306 iter->user_data3 = GINT_TO_POINTER(n);
1307 LEAVE(
"iter %s", iter_to_string(model, iter));
1326 ENTER(
"model %p, namespace %p, iter %p", model, name_space, iter);
1327 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
1328 g_return_val_if_fail ((name_space != NULL), FALSE);
1329 g_return_val_if_fail ((iter != NULL), FALSE);
1331 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
1337 n = g_list_index(list, name_space);
1341 iter->stamp = model->
stamp;
1342 iter->user_data = ITER_IS_NAMESPACE;
1343 iter->user_data2 = name_space;
1344 iter->user_data3 = GINT_TO_POINTER(n);
1345 LEAVE(
"iter %s", iter_to_string(model, iter));
1359 static GSList *pending_removals = NULL;
1377 GtkTreeModel *tree_model;
1378 GtkTreeIter tmp_iter;
1380 ENTER(
"model %p, iter (%p)%s", model, iter, iter_to_string(model, iter));
1390 while (model->
stamp == 0);
1391 iter->stamp = model->
stamp;
1394 tree_model = GTK_TREE_MODEL(model);
1395 path = gnc_tree_model_price_get_path (tree_model, iter);
1396 gtk_tree_model_row_inserted (tree_model, path, iter);
1403 if (gtk_tree_path_up(path) &&
1404 gtk_tree_path_get_depth(path) > 0 &&
1405 gtk_tree_model_get_iter(tree_model, &tmp_iter, path))
1408 gtk_tree_model_row_changed(tree_model, path, &tmp_iter);
1411 if (gtk_tree_model_iter_n_children(tree_model, &tmp_iter) == 1)
1412 gtk_tree_model_row_has_child_toggled(tree_model, path, &tmp_iter);
1415 while (gtk_tree_path_up(path) &&
1416 gtk_tree_path_get_depth(path) > 0 &&
1417 gtk_tree_model_get_iter(tree_model, &tmp_iter, path))
1419 gtk_tree_model_row_changed(tree_model, path, &tmp_iter);
1422 gtk_tree_path_free(path);
1428 if (gnc_tree_model_price_iter_has_child(tree_model, iter))
1430 path = gnc_tree_model_price_get_path(tree_model, iter);
1431 gtk_tree_model_row_has_child_toggled(tree_model, path, iter);
1432 gtk_tree_path_free(path);
1453 GtkTreeModel *tree_model;
1456 g_return_if_fail(GNC_IS_TREE_MODEL_PRICE(model));
1457 g_return_if_fail(path);
1459 debug_path(
ENTER, path);
1461 tree_model = GTK_TREE_MODEL(model);
1471 while (model->
stamp == 0);
1474 gtk_tree_model_row_deleted(tree_model, path);
1477 if (gtk_tree_path_up(path) &&
1478 gtk_tree_path_get_depth(path) > 0 &&
1479 gtk_tree_model_get_iter(tree_model, &iter, path))
1481 DEBUG(
"iter %s", iter_to_string(model, &iter));
1484 gtk_tree_model_row_changed(tree_model, path, &iter);
1487 if (!gtk_tree_model_iter_has_child(tree_model, &iter))
1488 gtk_tree_model_row_has_child_toggled(tree_model, path, &iter);
1491 while (gtk_tree_path_up(path) &&
1492 gtk_tree_path_get_depth(path) > 0 &&
1493 gtk_tree_model_get_iter(tree_model, &iter, path))
1495 DEBUG(
"iter %s", iter_to_string(model, &iter));
1496 gtk_tree_model_row_changed(tree_model, path, &iter);
1521 gnc_tree_model_price_do_deletions (gpointer unused)
1526 while (pending_removals)
1529 pending_removals = g_slist_delete_link(pending_removals, pending_removals);
1533 debug_path(
DEBUG, data->path);
1536 gnc_tree_model_price_row_delete(data->model, data->path);
1538 gtk_tree_path_free(data->path);
1581 gnc_tree_model_price_event_handler (
QofInstance *entity,
1584 gpointer event_data)
1592 ENTER(
"entity %p, event %d, model %p, event data %p",
1593 entity, event_type, user_data, event_data);
1597 if (pending_removals)
1598 gnc_tree_model_price_do_deletions(NULL);
1601 g_return_if_fail(GNC_IS_TREE_MODEL_PRICE(model));
1604 if (GNC_IS_COMMODITY(entity))
1608 commodity = GNC_COMMODITY(entity);
1610 if (event_type != QOF_EVENT_DESTROY)
1619 else if (GNC_IS_COMMODITY_NAMESPACE(entity))
1623 name_space = GNC_COMMODITY_NAMESPACE(entity);
1625 if (event_type != QOF_EVENT_DESTROY)
1634 else if (GNC_IS_PRICE(entity))
1638 price = GNC_PRICE(entity);
1640 if (event_type != QOF_EVENT_DESTROY)
1658 DEBUG(
"add %s", name);
1659 gnc_tree_model_price_row_add (model, &iter);
1662 case QOF_EVENT_REMOVE:
1664 DEBUG(
"remove %s", name);
1665 path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter);
1668 LEAVE(
"not in model");
1673 data->model = model;
1675 pending_removals = g_slist_append (pending_removals, data);
1676 g_idle_add_full(G_PRIORITY_HIGH_IDLE,
1677 gnc_tree_model_price_do_deletions, NULL, NULL);
1682 case QOF_EVENT_MODIFY:
1683 DEBUG(
"change %s", name);
1684 path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter);
1687 LEAVE(
"not in model");
1690 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &iter, path))
1692 gtk_tree_path_free(path);
1693 LEAVE(
"can't find iter for path");
1696 gtk_tree_model_row_changed(GTK_TREE_MODEL(model), path, &iter);
1697 gtk_tree_path_free(path);
1702 LEAVE(
"ignored event for %s", name);
void gnc_price_list_destroy(PriceList *prices)
gboolean gnc_tree_model_price_get_iter_from_price(GncTreeModelPrice *model, GNCPrice *price, GtkTreeIter *iter)
gnc_commodity * gnc_tree_model_price_get_commodity(GncTreeModelPrice *model, GtkTreeIter *iter)
const char * gnc_print_date(Timespec ts)
const GList * gnc_gobject_tracking_get_list(const gchar *name)
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
a simple price database for gnucash
gboolean gnc_tree_model_price_get_iter_from_namespace(GncTreeModelPrice *model, gnc_commodity_namespace *name_space, GtkTreeIter *iter)
utility functions for the GnuCash UI
GtkTreeModel implementation for gnucash price database.
#define DEBUG(format, args...)
GNCPrice * gnc_tree_model_price_get_price(GncTreeModelPrice *model, GtkTreeIter *iter)
gnc_commodity_namespace * gnc_tree_model_price_get_namespace(GncTreeModelPrice *model, GtkTreeIter *iter)
#define ENTER(format, args...)
GList * gnc_commodity_namespace_get_commodity_list(const gnc_commodity_namespace *name_space)
const char * gnc_commodity_namespace_get_name(const gnc_commodity_namespace *ns)
gboolean gnc_tree_model_price_iter_is_namespace(GncTreeModelPrice *model, GtkTreeIter *iter)
gint qof_event_register_handler(QofEventHandler handler, gpointer handler_data)
Register a handler for events.
gboolean gnc_tree_model_price_iter_is_commodity(GncTreeModelPrice *model, GtkTreeIter *iter)
void qof_event_unregister_handler(gint handler_id)
Unregister an event handler.
gboolean gnc_tree_model_price_iter_is_price(GncTreeModelPrice *model, GtkTreeIter *iter)
All type declarations for the whole Gnucash engine.
gboolean gnc_pricedb_has_prices(GNCPriceDB *db, const gnc_commodity *commodity, const gnc_commodity *currency)
GType gnc_tree_model_price_get_type(void)
const char * gnc_commodity_get_printname(const gnc_commodity *cm)
GtkTreeModel * gnc_tree_model_price_new(QofBook *book, GNCPriceDB *price_db)
GtkTreePath * gnc_tree_model_price_get_path_from_price(GncTreeModelPrice *model, GNCPrice *price)
gnc_commodity_namespace * gnc_commodity_get_namespace_ds(const gnc_commodity *cm)
#define LEAVE(format, args...)
gpointer qof_book_get_data(const QofBook *book, const gchar *key)
GList * gnc_commodity_table_get_namespaces_list(const gnc_commodity_table *table)
const gchar * QofLogModule
gboolean gnc_tree_model_price_get_iter_from_commodity(GncTreeModelPrice *model, gnc_commodity *commodity, GtkTreeIter *iter)
PriceList * gnc_pricedb_get_prices(GNCPriceDB *db, const gnc_commodity *commodity, const gnc_commodity *currency)