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 82 static QofLogModule log_module = GNC_MOD_GUI;
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);
129 GNCPriceDB *price_db;
130 gint event_handler_id;
134 #define GNC_TREE_MODEL_PRICE_GET_PRIVATE(o) \ 135 ((GncTreeModelPricePrivate*)gnc_tree_model_price_get_instance_private((GncTreeModelPrice*)o)) 138 static GObjectClass *parent_class = NULL;
140 G_DEFINE_TYPE_WITH_CODE(
GncTreeModelPrice, gnc_tree_model_price, GNC_TYPE_TREE_MODEL,
142 G_IMPLEMENT_INTERFACE(GTK_TYPE_TREE_MODEL,
143 gnc_tree_model_price_tree_model_init))
148 GObjectClass *o_class = G_OBJECT_CLASS (klass);
150 parent_class = g_type_class_peek_parent (klass);
152 o_class->finalize = gnc_tree_model_price_finalize;
153 o_class->dispose = gnc_tree_model_price_dispose;
161 while (model->
stamp == 0)
163 model->
stamp = g_random_int ();
166 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
167 priv->print_info = gnc_default_price_print_info(NULL);
171 gnc_tree_model_price_finalize (GObject *
object)
176 ENTER(
"model %p",
object);
178 g_return_if_fail (
object != NULL);
179 g_return_if_fail (GNC_IS_TREE_MODEL_PRICE (
object));
181 model = GNC_TREE_MODEL_PRICE (
object);
182 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
185 priv->price_db = NULL;
187 G_OBJECT_CLASS (parent_class)->finalize (
object);
192 gnc_tree_model_price_dispose (GObject *
object)
197 ENTER(
"model %p",
object);
198 g_return_if_fail (
object != NULL);
199 g_return_if_fail (GNC_IS_TREE_MODEL_PRICE (
object));
201 model = GNC_TREE_MODEL_PRICE (
object);
202 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
204 if (priv->event_handler_id)
207 priv->event_handler_id = 0;
210 if (G_OBJECT_CLASS (parent_class)->dispose)
211 G_OBJECT_CLASS (parent_class)->dispose (
object);
225 for ( ; item; item = g_list_next(item))
228 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
229 if (priv->price_db == price_db)
231 g_object_ref(G_OBJECT(model));
232 LEAVE(
"returning existing model %p", model);
233 return GTK_TREE_MODEL(model);
237 model = g_object_new (GNC_TYPE_TREE_MODEL_PRICE, NULL);
239 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
241 priv->price_db = price_db;
243 priv->event_handler_id =
246 LEAVE(
"returning new model %p", model);
247 return GTK_TREE_MODEL (model);
254 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
255 g_return_val_if_fail (iter != NULL, FALSE);
256 g_return_val_if_fail (iter->user_data != NULL, FALSE);
257 g_return_val_if_fail (iter->stamp == model->
stamp, FALSE);
259 return (iter->user_data == ITER_IS_NAMESPACE);
266 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
267 g_return_val_if_fail (iter != NULL, FALSE);
268 g_return_val_if_fail (iter->user_data != NULL, FALSE);
269 g_return_val_if_fail (iter->stamp == model->
stamp, FALSE);
271 return (iter->user_data == ITER_IS_COMMODITY);
278 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
279 g_return_val_if_fail (iter != NULL, FALSE);
280 g_return_val_if_fail (iter->user_data != NULL, FALSE);
281 g_return_val_if_fail (iter->stamp == model->
stamp, FALSE);
283 return (iter->user_data == ITER_IS_PRICE);
286 gnc_commodity_namespace *
290 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), NULL);
291 g_return_val_if_fail (iter != NULL, NULL);
292 g_return_val_if_fail (iter->user_data != NULL, NULL);
293 g_return_val_if_fail (iter->stamp == model->
stamp, NULL);
295 if (iter->user_data != ITER_IS_NAMESPACE)
297 return (gnc_commodity_namespace *)iter->user_data2;
304 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), NULL);
305 g_return_val_if_fail (iter != NULL, NULL);
306 g_return_val_if_fail (iter->user_data != NULL, NULL);
307 g_return_val_if_fail (iter->stamp == model->
stamp, NULL);
309 if (iter->user_data != ITER_IS_COMMODITY)
311 return (gnc_commodity *)iter->user_data2;
318 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), NULL);
319 g_return_val_if_fail (iter != NULL, NULL);
320 g_return_val_if_fail (iter->user_data != NULL, NULL);
321 g_return_val_if_fail (iter->stamp == model->
stamp, NULL);
323 if (iter->user_data != ITER_IS_PRICE)
325 return (GNCPrice *)iter->user_data2;
332 #define debug_path(fn, path) { \ 333 gchar *path_string = gtk_tree_path_to_string(path); \ 334 fn("tree path %s", path_string? path_string : "(NULL)"); \ 335 g_free(path_string); \ 338 #define ITER_STRING_LEN 256 344 gnc_commodity_namespace *name_space;
345 gnc_commodity *commodity;
347 #ifdef G_THREADS_ENABLED 348 static GPrivate gtmits_buffer_key = G_PRIVATE_INIT(g_free);
351 string = g_private_get (>mits_buffer_key);
354 string = g_malloc(ITER_STRING_LEN + 1);
355 g_private_set (>mits_buffer_key,
string);
358 static char string[ITER_STRING_LEN + 1];
361 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
364 switch (GPOINTER_TO_INT(iter->user_data))
366 case GPOINTER_TO_INT(ITER_IS_NAMESPACE):
367 name_space = (gnc_commodity_namespace *) iter->user_data2;
368 snprintf(
string, ITER_STRING_LEN,
369 "[stamp:%x data:%d (NAMESPACE), %p (%s), %d]",
370 iter->stamp, GPOINTER_TO_INT(iter->user_data),
372 GPOINTER_TO_INT(iter->user_data3));
375 case GPOINTER_TO_INT(ITER_IS_COMMODITY):
376 commodity = (gnc_commodity *) iter->user_data2;
377 snprintf(
string, ITER_STRING_LEN,
378 "[stamp:%x data:%d (COMMODITY), %p (%s), %d]",
379 iter->stamp, GPOINTER_TO_INT(iter->user_data),
381 GPOINTER_TO_INT(iter->user_data3));
384 case GPOINTER_TO_INT(ITER_IS_PRICE):
385 price = (GNCPrice *) iter->user_data2;
386 commodity = gnc_price_get_commodity(price);
387 snprintf(
string, ITER_STRING_LEN,
388 "[stamp:%x data:%d (PRICE), %p (%s:%s), %d]",
389 iter->stamp, GPOINTER_TO_INT(iter->user_data),
392 GPOINTER_TO_INT(iter->user_data3));
396 snprintf(
string, ITER_STRING_LEN,
397 "[stamp:%x data:%d (UNKNOWN), %p, %d]",
399 GPOINTER_TO_INT(iter->user_data),
401 GPOINTER_TO_INT(iter->user_data3));
414 gnc_tree_model_price_tree_model_init (GtkTreeModelIface *iface)
416 iface->get_flags = gnc_tree_model_price_get_flags;
417 iface->get_n_columns = gnc_tree_model_price_get_n_columns;
418 iface->get_column_type = gnc_tree_model_price_get_column_type;
419 iface->get_iter = gnc_tree_model_price_get_iter;
420 iface->get_path = gnc_tree_model_price_get_path;
421 iface->get_value = gnc_tree_model_price_get_value;
422 iface->iter_next = gnc_tree_model_price_iter_next;
423 iface->iter_children = gnc_tree_model_price_iter_children;
424 iface->iter_has_child = gnc_tree_model_price_iter_has_child;
425 iface->iter_n_children = gnc_tree_model_price_iter_n_children;
426 iface->iter_nth_child = gnc_tree_model_price_iter_nth_child;
427 iface->iter_parent = gnc_tree_model_price_iter_parent;
431 gnc_tree_model_price_get_flags (GtkTreeModel *tree_model)
437 gnc_tree_model_price_get_n_columns (GtkTreeModel *tree_model)
439 return GNC_TREE_MODEL_PRICE_NUM_COLUMNS;
443 gnc_tree_model_price_get_column_type (GtkTreeModel *tree_model,
446 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), G_TYPE_INVALID);
447 g_return_val_if_fail ((index < GNC_TREE_MODEL_PRICE_NUM_COLUMNS) && (index >= 0), G_TYPE_INVALID);
451 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
452 case GNC_TREE_MODEL_PRICE_COL_CURRENCY:
453 case GNC_TREE_MODEL_PRICE_COL_DATE:
454 case GNC_TREE_MODEL_PRICE_COL_SOURCE:
455 case GNC_TREE_MODEL_PRICE_COL_TYPE:
456 case GNC_TREE_MODEL_PRICE_COL_VALUE:
457 return G_TYPE_STRING;
458 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
459 return G_TYPE_BOOLEAN;
461 g_assert_not_reached ();
462 return G_TYPE_INVALID;
467 gnc_tree_model_price_get_iter (GtkTreeModel *tree_model,
473 gnc_commodity_table *ct;
474 gnc_commodity_namespace *name_space;
475 gnc_commodity *commodity = NULL;
477 GList *ns_list, *cm_list;
480 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), FALSE);
482 depth = gtk_tree_path_get_depth (path);
483 ENTER(
"model %p, iter %p, path %p (depth %d)", tree_model, iter, path, depth);
484 debug_path(
DEBUG, path);
489 LEAVE(
"depth too small");
494 LEAVE(
"depth too big");
499 model = GNC_TREE_MODEL_PRICE (tree_model);
500 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
501 if (priv->price_db == NULL)
503 LEAVE(
"no price db");
510 i = gtk_tree_path_get_indices (path)[0];
511 name_space = g_list_nth_data (ns_list, i);
514 LEAVE(
"invalid path at namespace");
521 iter->stamp = model->
stamp;
522 iter->user_data = ITER_IS_NAMESPACE;
523 iter->user_data2 = name_space;
524 iter->user_data3 = GINT_TO_POINTER(i);
525 LEAVE(
"iter (ns) %s", iter_to_string(model, iter));
531 i = gtk_tree_path_get_indices (path)[1];
532 commodity = g_list_nth_data (cm_list, i);
535 LEAVE(
"invalid path at commodity");
542 iter->stamp = model->
stamp;
543 iter->user_data = ITER_IS_COMMODITY;
544 iter->user_data2 = commodity;
545 iter->user_data3 = GINT_TO_POINTER(i);
546 LEAVE(
"iter (cm) %s", iter_to_string(model, iter));
551 i = gtk_tree_path_get_indices (path)[2];
556 #ifdef RACE_CONDITION_SOLVED 559 LEAVE(
"invalid path at price");
565 iter->stamp = model->
stamp;
566 iter->user_data = ITER_IS_PRICE;
567 iter->user_data2 = price;
568 iter->user_data3 = GINT_TO_POINTER(i);
569 LEAVE(
"iter (pc) %s", iter_to_string(model, iter));
574 gnc_tree_model_price_get_path (GtkTreeModel *tree_model,
579 gnc_commodity_table *ct;
580 gnc_commodity_namespace *name_space;
581 gnc_commodity *commodity;
582 GList *ns_list, *cm_list;
585 ENTER(
"model %p, iter %p (%s)", tree_model, iter, iter_to_string(model, iter));
586 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), NULL);
587 g_return_val_if_fail (iter != NULL, NULL);
588 g_return_val_if_fail (iter->user_data != NULL, NULL);
589 g_return_val_if_fail (iter->stamp == model->
stamp, NULL);
592 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
593 if (priv->price_db == NULL)
595 LEAVE(
"no price db");
599 if (iter->user_data == ITER_IS_NAMESPACE)
603 path = gtk_tree_path_new ();
604 gtk_tree_path_append_index (path, GPOINTER_TO_INT(iter->user_data3));
605 debug_path(
LEAVE, path);
613 if (iter->user_data == ITER_IS_COMMODITY)
616 commodity = (gnc_commodity*)iter->user_data2;
618 path = gtk_tree_path_new ();
619 gtk_tree_path_append_index (path, g_list_index (ns_list, name_space));
620 gtk_tree_path_append_index (path, GPOINTER_TO_INT(iter->user_data3));
621 debug_path(
LEAVE, path);
626 commodity = gnc_price_get_commodity((GNCPrice*)iter->user_data2);
629 path = gtk_tree_path_new ();
630 gtk_tree_path_append_index (path, g_list_index (ns_list, name_space));
631 gtk_tree_path_append_index (path, g_list_index (cm_list, commodity));
632 gtk_tree_path_append_index (path, GPOINTER_TO_INT(iter->user_data3));
633 debug_path(
LEAVE, path);
638 gnc_tree_model_price_get_value (GtkTreeModel *tree_model,
645 gnc_commodity_namespace *name_space;
646 gnc_commodity *commodity;
649 memset (datebuff, 0,
sizeof(datebuff));
651 g_return_if_fail (GNC_IS_TREE_MODEL_PRICE (model));
652 g_return_if_fail (iter != NULL);
653 #ifdef RACE_CONDITION_SOLVED 654 g_return_if_fail (iter->user_data != NULL);
656 g_return_if_fail (iter->stamp == model->
stamp);
658 if (iter->user_data == ITER_IS_NAMESPACE)
660 name_space = (gnc_commodity_namespace *)iter->user_data2;
663 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
664 g_value_init (value, G_TYPE_STRING);
667 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
668 g_value_init (value, G_TYPE_BOOLEAN);
669 g_value_set_boolean (value, FALSE);
672 g_value_init (value, G_TYPE_STRING);
673 g_value_set_string (value,
"");
679 if (iter->user_data == ITER_IS_COMMODITY)
681 commodity = (gnc_commodity *)iter->user_data2;
684 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
685 g_value_init (value, G_TYPE_STRING);
688 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
689 g_value_init (value, G_TYPE_BOOLEAN);
690 g_value_set_boolean (value, FALSE);
693 g_value_init (value, G_TYPE_STRING);
694 g_value_set_string (value,
"");
700 price = (GNCPrice *)iter->user_data2;
701 #ifdef RACE_CONDITION_SOLVED
702 g_return_if_fail (price != NULL);
708 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
709 g_value_init (value, G_TYPE_STRING);
710 g_value_set_string (value,
"");
712 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
713 g_value_init (value, G_TYPE_BOOLEAN);
714 g_value_set_boolean (value, FALSE);
717 g_value_init (value, G_TYPE_STRING);
718 g_value_set_string (value,
"");
727 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
728 g_value_init (value, G_TYPE_STRING);
729 commodity = gnc_price_get_commodity (price);
732 case GNC_TREE_MODEL_PRICE_COL_CURRENCY:
733 g_value_init (value, G_TYPE_STRING);
734 commodity = gnc_price_get_currency (price);
737 case GNC_TREE_MODEL_PRICE_COL_DATE:
739 gnc_price_get_time64 (price));
740 g_value_init (value, G_TYPE_STRING);
741 g_value_set_string (value, datebuff);
743 case GNC_TREE_MODEL_PRICE_COL_SOURCE:
744 g_value_init (value, G_TYPE_STRING);
745 g_value_set_string (value, gettext (gnc_price_get_source_string (price)));
747 case GNC_TREE_MODEL_PRICE_COL_TYPE:
748 g_value_init (value, G_TYPE_STRING);
749 g_value_set_string (value, gnc_price_get_typestr (price));
751 case GNC_TREE_MODEL_PRICE_COL_VALUE:
752 g_value_init (value, G_TYPE_STRING);
753 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
754 g_value_set_string (value,
xaccPrintAmount (gnc_price_get_value (price),
757 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
758 g_value_init (value, G_TYPE_BOOLEAN);
759 g_value_set_boolean (value, TRUE);
762 g_assert_not_reached ();
767 gnc_tree_model_price_iter_next (GtkTreeModel *tree_model,
772 gnc_commodity_table *ct;
773 gnc_commodity *commodity;
774 gnc_commodity_namespace *name_space;
778 ENTER(
"model %p, iter %p(%s)", tree_model, iter, iter_to_string(model, iter));
779 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
780 g_return_val_if_fail (iter != NULL, FALSE);
781 g_return_val_if_fail (iter->user_data != NULL, FALSE);
782 g_return_val_if_fail (iter->stamp == model->
stamp, FALSE);
784 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
785 if (iter->user_data == ITER_IS_NAMESPACE)
789 n = GPOINTER_TO_INT(iter->user_data3) + 1;
790 iter->user_data2 = g_list_nth_data(list, n);
791 if (iter->user_data2 == NULL)
793 LEAVE(
"no next iter");
796 iter->user_data3 = GINT_TO_POINTER(n);
797 LEAVE(
"iter %p(%s)", iter, iter_to_string(model, iter));
800 else if (iter->user_data == ITER_IS_COMMODITY)
804 n = GPOINTER_TO_INT(iter->user_data3) + 1;
805 iter->user_data2 = g_list_nth_data(list, n);
806 if (iter->user_data2 == NULL)
808 LEAVE(
"no next iter");
811 iter->user_data3 = GINT_TO_POINTER(n);
812 LEAVE(
"iter %p(%s)", iter, iter_to_string(model, iter));
815 else if (iter->user_data == ITER_IS_PRICE)
817 commodity = gnc_price_get_commodity((GNCPrice*)iter->user_data2);
818 n = GPOINTER_TO_INT(iter->user_data3) + 1;
820 if (iter->user_data2 == NULL)
822 LEAVE(
"no next iter");
825 iter->user_data3 = GINT_TO_POINTER(n);
826 LEAVE(
"iter %p(%s)", iter, iter_to_string(model, iter));
831 LEAVE(
"unknown iter type");
837 gnc_tree_model_price_iter_children (GtkTreeModel *tree_model,
843 gnc_commodity_table *ct;
844 gnc_commodity_namespace *name_space;
845 gnc_commodity *commodity;
848 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), FALSE);
850 model = GNC_TREE_MODEL_PRICE (tree_model);
851 ENTER(
"model %p, iter %p, parent %p (%s)",
852 tree_model, iter, parent, iter_to_string(model, parent));
854 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
861 LEAVE(
"no namespaces");
865 iter->stamp = model->
stamp;
866 iter->user_data = ITER_IS_NAMESPACE;
867 iter->user_data2 = g_list_nth_data(list, 0);
868 iter->user_data3 = GINT_TO_POINTER(0);
869 LEAVE(
"ns iter %p (%s)", iter, iter_to_string(model, iter));
873 if (parent->user_data == ITER_IS_NAMESPACE)
875 name_space = (gnc_commodity_namespace *)parent->user_data2;
879 LEAVE(
"no commodities");
883 iter->stamp = model->
stamp;
884 iter->user_data = ITER_IS_COMMODITY;
885 iter->user_data2 = g_list_nth_data(list, 0);
886 iter->user_data3 = GINT_TO_POINTER(0);
887 LEAVE(
"cm iter %p (%s)", iter, iter_to_string(model, iter));
891 if (parent->user_data == ITER_IS_COMMODITY)
894 commodity = (gnc_commodity *)parent->user_data2;
901 iter->stamp = model->
stamp;
902 iter->user_data = ITER_IS_PRICE;
903 iter->user_data2 = price;
904 iter->user_data3 = GINT_TO_POINTER(0);
905 LEAVE(
"price iter %p (%s)", iter, iter_to_string(model, iter));
914 gnc_tree_model_price_iter_has_child (GtkTreeModel *tree_model,
919 gnc_commodity_namespace *name_space;
920 gnc_commodity *commodity;
924 model = GNC_TREE_MODEL_PRICE (tree_model);
925 ENTER(
"model %p, iter %p (%s)", tree_model,
926 iter, iter_to_string(model, iter));
927 g_return_val_if_fail (tree_model != NULL, FALSE);
928 g_return_val_if_fail (iter != NULL, FALSE);
930 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
931 if (iter->user_data == ITER_IS_PRICE)
933 LEAVE(
"price has no children");
937 if (iter->user_data == ITER_IS_NAMESPACE)
939 name_space = (gnc_commodity_namespace *)iter->user_data2;
941 LEAVE(
"%s children", list ?
"has" :
"no");
945 if (iter->user_data == ITER_IS_COMMODITY)
947 commodity = (gnc_commodity *)iter->user_data2;
949 LEAVE(
"%s children", result ?
"has" :
"no");
953 LEAVE(
"no children (unknown type)");
958 gnc_tree_model_price_iter_n_children (GtkTreeModel *tree_model,
963 gnc_commodity_table *ct;
964 gnc_commodity_namespace *name_space;
965 gnc_commodity *commodity;
969 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), -1);
971 model = GNC_TREE_MODEL_PRICE (tree_model);
972 ENTER(
"model %p, iter %p (%s)", tree_model, iter,
973 iter_to_string(model, iter));
975 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
980 LEAVE(
"ns list length %d", g_list_length(list));
981 return g_list_length (list);
984 if (iter->user_data == ITER_IS_NAMESPACE)
986 name_space = (gnc_commodity_namespace *)iter->user_data2;
988 LEAVE(
"cm list length %d", g_list_length(list));
989 return g_list_length (list);
992 if (iter->user_data == ITER_IS_COMMODITY)
994 commodity = (gnc_commodity *)iter->user_data2;
996 LEAVE(
"price list length %d", n);
1005 gnc_tree_model_price_iter_nth_child (GtkTreeModel *tree_model,
1007 GtkTreeIter *parent,
1012 gnc_commodity_table *ct;
1013 gnc_commodity_namespace *name_space;
1014 gnc_commodity *commodity;
1017 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), FALSE);
1018 g_return_val_if_fail (iter != NULL, FALSE);
1020 model = GNC_TREE_MODEL_PRICE (tree_model);
1021 ENTER(
"model %p, iter %p, parent %p (%s), n %d",
1022 tree_model, iter, parent, iter_to_string(model, parent), n);
1024 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
1030 iter->stamp = model->
stamp;
1031 iter->user_data = ITER_IS_NAMESPACE;
1032 iter->user_data2 = g_list_nth_data(list, n);
1033 iter->user_data3 = GINT_TO_POINTER(n);
1034 LEAVE(
"ns iter %p (%s)", iter, iter_to_string(model, iter));
1035 return iter->user_data2 != NULL;
1038 if (parent->user_data == ITER_IS_NAMESPACE)
1040 name_space = (gnc_commodity_namespace *)parent->user_data2;
1043 iter->stamp = model->
stamp;
1044 iter->user_data = ITER_IS_COMMODITY;
1045 iter->user_data2 = g_list_nth_data(list, n);
1046 iter->user_data3 = GINT_TO_POINTER(n);
1047 LEAVE(
"cm iter %p (%s)", iter, iter_to_string(model, iter));
1048 return iter->user_data2 != NULL;
1051 if (parent->user_data == ITER_IS_COMMODITY)
1053 commodity = (gnc_commodity *)parent->user_data2;
1055 iter->stamp = model->
stamp;
1056 iter->user_data = ITER_IS_PRICE;
1058 iter->user_data3 = GINT_TO_POINTER(n);
1059 LEAVE(
"price iter %p (%s)", iter, iter_to_string(model, iter));
1060 return iter->user_data2 != NULL;
1069 gnc_tree_model_price_iter_parent (GtkTreeModel *tree_model,
1075 gnc_commodity_table *ct;
1076 gnc_commodity * commodity;
1077 gnc_commodity_namespace *name_space;
1080 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), FALSE);
1081 g_return_val_if_fail (iter != NULL, FALSE);
1082 g_return_val_if_fail (child != NULL, FALSE);
1084 model = GNC_TREE_MODEL_PRICE (tree_model);
1085 ENTER(
"model %p, iter %p, child %p (%s)",
1086 tree_model, iter, child, iter_to_string(model, child));
1088 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
1089 if (child->user_data == ITER_IS_NAMESPACE)
1091 LEAVE(
"ns has no parent");
1095 if (child->user_data == ITER_IS_COMMODITY)
1101 iter->stamp = model->
stamp;
1102 iter->user_data = ITER_IS_NAMESPACE;
1103 iter->user_data2 = name_space;
1104 iter->user_data3 = GINT_TO_POINTER(g_list_index(list, name_space));
1105 LEAVE(
"ns iter %p (%s)", iter, iter_to_string(model, iter));
1109 commodity = gnc_price_get_commodity ((GNCPrice*)child->user_data2);
1113 iter->stamp = model->
stamp;
1114 iter->user_data = ITER_IS_COMMODITY;
1115 iter->user_data2 = commodity;
1116 iter->user_data3 = GINT_TO_POINTER(g_list_index(list, commodity));
1117 LEAVE(
"cm iter %p (%s)", iter, iter_to_string(model, iter));
1136 gnc_commodity *commodity;
1140 ENTER(
"model %p, price %p, iter %p", model, price, iter);
1141 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
1142 g_return_val_if_fail ((price != NULL), FALSE);
1143 g_return_val_if_fail ((iter != NULL), FALSE);
1145 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
1146 commodity = gnc_price_get_commodity(price);
1147 if (commodity == NULL)
1149 LEAVE(
"no commodity");
1156 LEAVE(
"empty list");
1160 n = g_list_index(list, price);
1164 LEAVE(
"not in list");
1168 iter->stamp = model->
stamp;
1169 iter->user_data = ITER_IS_PRICE;
1170 iter->user_data2 = price;
1171 iter->user_data3 = GINT_TO_POINTER(n);
1173 LEAVE(
"iter %s", iter_to_string(model, iter));
1186 GtkTreeIter tree_iter;
1187 GtkTreePath *tree_path;
1189 ENTER(
"model %p, price %p", model, price);
1190 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), NULL);
1191 g_return_val_if_fail (price != NULL, NULL);
1199 tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &tree_iter);
1202 gchar *path_string = gtk_tree_path_to_string(tree_path);
1203 LEAVE(
"path (2) %s", path_string);
1204 g_free(path_string);
1220 gnc_commodity *commodity,
1223 gnc_commodity_namespace *name_space;
1227 ENTER(
"model %p, commodity %p, iter %p", model, commodity, iter);
1228 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
1229 g_return_val_if_fail ((commodity != NULL), FALSE);
1230 g_return_val_if_fail ((iter != NULL), FALSE);
1233 if (name_space == NULL)
1235 LEAVE(
"no namespace");
1242 LEAVE(
"empty list");
1246 n = g_list_index(list, commodity);
1249 LEAVE(
"commodity not in list");
1253 iter->stamp = model->
stamp;
1254 iter->user_data = ITER_IS_COMMODITY;
1255 iter->user_data2 = commodity;
1256 iter->user_data3 = GINT_TO_POINTER(n);
1257 LEAVE(
"iter %s", iter_to_string(model, iter));
1268 gnc_commodity_namespace *name_space,
1272 gnc_commodity_table *ct;
1276 ENTER(
"model %p, namespace %p, iter %p", model, name_space, iter);
1277 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
1278 g_return_val_if_fail ((name_space != NULL), FALSE);
1279 g_return_val_if_fail ((iter != NULL), FALSE);
1281 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
1286 LEAVE(
"namespace list empty");
1290 n = g_list_index(list, name_space);
1293 LEAVE(
"namespace not found");
1297 iter->stamp = model->
stamp;
1298 iter->user_data = ITER_IS_NAMESPACE;
1299 iter->user_data2 = name_space;
1300 iter->user_data3 = GINT_TO_POINTER(n);
1301 LEAVE(
"iter %s", iter_to_string(model, iter));
1309 typedef struct _remove_data
1315 static GSList *pending_removals = NULL;
1333 GtkTreeModel *tree_model;
1334 GtkTreeIter tmp_iter;
1336 ENTER(
"model %p, iter (%p)%s", model, iter, iter_to_string(model, iter));
1346 while (model->
stamp == 0);
1347 iter->stamp = model->
stamp;
1350 tree_model = GTK_TREE_MODEL(model);
1351 path = gnc_tree_model_price_get_path (tree_model, iter);
1352 gtk_tree_model_row_inserted (tree_model, path, iter);
1359 if (gtk_tree_path_up(path) &&
1360 gtk_tree_path_get_depth(path) > 0 &&
1361 gtk_tree_model_get_iter(tree_model, &tmp_iter, path))
1364 gtk_tree_model_row_changed(tree_model, path, &tmp_iter);
1367 if (gtk_tree_model_iter_n_children(tree_model, &tmp_iter) == 1)
1368 gtk_tree_model_row_has_child_toggled(tree_model, path, &tmp_iter);
1371 while (gtk_tree_path_up(path) &&
1372 gtk_tree_path_get_depth(path) > 0 &&
1373 gtk_tree_model_get_iter(tree_model, &tmp_iter, path))
1375 gtk_tree_model_row_changed(tree_model, path, &tmp_iter);
1378 gtk_tree_path_free(path);
1384 if (gnc_tree_model_price_iter_has_child(tree_model, iter))
1386 path = gnc_tree_model_price_get_path(tree_model, iter);
1387 gtk_tree_model_row_has_child_toggled(tree_model, path, iter);
1388 gtk_tree_path_free(path);
1409 GtkTreeModel *tree_model;
1412 g_return_if_fail(GNC_IS_TREE_MODEL_PRICE(model));
1413 g_return_if_fail(path);
1415 debug_path(
ENTER, path);
1417 tree_model = GTK_TREE_MODEL(model);
1427 while (model->
stamp == 0);
1430 gtk_tree_model_row_deleted(tree_model, path);
1433 if (gtk_tree_path_up(path) &&
1434 gtk_tree_path_get_depth(path) > 0 &&
1435 gtk_tree_model_get_iter(tree_model, &iter, path))
1437 DEBUG(
"iter %s", iter_to_string(model, &iter));
1440 gtk_tree_model_row_changed(tree_model, path, &iter);
1443 if (!gtk_tree_model_iter_has_child(tree_model, &iter))
1444 gtk_tree_model_row_has_child_toggled(tree_model, path, &iter);
1447 while (gtk_tree_path_up(path) &&
1448 gtk_tree_path_get_depth(path) > 0 &&
1449 gtk_tree_model_get_iter(tree_model, &iter, path))
1451 DEBUG(
"iter %s", iter_to_string(model, &iter));
1452 gtk_tree_model_row_changed(tree_model, path, &iter);
1477 gnc_tree_model_price_do_deletions (gpointer price_db)
1482 while (pending_removals)
1485 pending_removals = g_slist_delete_link(pending_removals, pending_removals);
1489 debug_path(
DEBUG, data->path);
1492 gnc_tree_model_price_row_delete(data->model, data->path);
1493 gnc_pricedb_nth_price_reset_cache (price_db);
1495 gtk_tree_path_free(data->path);
1538 gnc_tree_model_price_event_handler (QofInstance *entity,
1541 gpointer event_data)
1550 ENTER(
"entity %p, event %d, model %p, event data %p",
1551 entity, event_type, user_data, event_data);
1553 priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);
1556 if (pending_removals)
1557 gnc_tree_model_price_do_deletions (priv->price_db);
1560 g_return_if_fail(GNC_IS_TREE_MODEL_PRICE(model));
1563 if (GNC_IS_COMMODITY(entity))
1565 gnc_commodity *commodity;
1567 commodity = GNC_COMMODITY(entity);
1569 if (event_type != QOF_EVENT_DESTROY)
1578 else if (GNC_IS_COMMODITY_NAMESPACE(entity))
1580 gnc_commodity_namespace *name_space;
1582 name_space = GNC_COMMODITY_NAMESPACE(entity);
1584 if (event_type != QOF_EVENT_DESTROY)
1593 else if (GNC_IS_PRICE(entity))
1597 price = GNC_PRICE(entity);
1599 if (event_type != QOF_EVENT_DESTROY)
1618 DEBUG(
"add %s", name);
1619 gnc_pricedb_nth_price_reset_cache (priv->price_db);
1620 gnc_tree_model_price_row_add (model, &iter);
1623 case QOF_EVENT_REMOVE:
1625 DEBUG(
"remove %s", name);
1626 path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter);
1629 LEAVE(
"not in model");
1634 data->model = model;
1636 pending_removals = g_slist_append (pending_removals, data);
1637 g_idle_add_full(G_PRIORITY_HIGH_IDLE,
1638 gnc_tree_model_price_do_deletions, priv->price_db, NULL);
1643 case QOF_EVENT_MODIFY:
1644 DEBUG(
"change %s", name);
1645 path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter);
1648 LEAVE(
"not in model");
1651 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &iter, path))
1653 gtk_tree_path_free(path);
1654 LEAVE(
"can't find iter for path");
1657 gtk_tree_model_row_changed(GTK_TREE_MODEL(model), path, &iter);
1658 gtk_tree_path_free(path);
1663 LEAVE(
"ignored event for %s", name);
void gnc_price_list_destroy(PriceList *prices)
gnc_price_list_destroy - destroy the given price list, calling gnc_price_unref on all the prices incl...
gboolean gnc_tree_model_price_get_iter_from_price(GncTreeModelPrice *model, GNCPrice *price, GtkTreeIter *iter)
Convert a price pointer into a GtkTreeIter.
The instance private data for a price database tree model.
GNCPrice * gnc_pricedb_nth_price(GNCPriceDB *db, const gnc_commodity *c, const int n)
Get the nth price for the given commodity in reverse date order.
gnc_commodity * gnc_tree_model_price_get_commodity(GncTreeModelPrice *model, GtkTreeIter *iter)
Convert a model/iter pair to a gnucash commodity.
const GList * gnc_gobject_tracking_get_list(const gchar *name)
Get a list of all known objects of a specified type.
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic for the specified commodity.
int stamp
The state of the model.
a simple price database for gnucash
const char * gnc_commodity_namespace_get_gui_name(const gnc_commodity_namespace *ns)
Return the textual name of a namespace data structure in a form suitable to present to the user...
gboolean gnc_tree_model_price_get_iter_from_namespace(GncTreeModelPrice *model, gnc_commodity_namespace *name_space, GtkTreeIter *iter)
Convert a commodity namespace pointer into a GtkTreeIter.
utility functions for the GnuCash UI
GtkTreeModel implementation for gnucash price database.
int gnc_pricedb_num_prices(GNCPriceDB *db, const gnc_commodity *c)
Get the number of prices, in any currency, for a given commodity.
#define DEBUG(format, args...)
Print a debugging message.
GNCPrice * gnc_tree_model_price_get_price(GncTreeModelPrice *model, GtkTreeIter *iter)
Convert a model/iter pair to a gnucash price.
const char * xaccPrintAmount(gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
gnc_commodity_namespace * gnc_tree_model_price_get_namespace(GncTreeModelPrice *model, GtkTreeIter *iter)
Convert a model/iter pair to a gnucash commodity namespace.
#define ENTER(format, args...)
Print a function entry debugging message.
GList * gnc_commodity_namespace_get_commodity_list(const gnc_commodity_namespace *name_space)
Return a list of all commodity data structures in the specified namespace.
const char * gnc_commodity_namespace_get_name(const gnc_commodity_namespace *ns)
Return the textual name of a namespace data structure.
gboolean gnc_tree_model_price_iter_is_namespace(GncTreeModelPrice *model, GtkTreeIter *iter)
Determine whether or not the specified GtkTreeIter points to a "commodity namespace".
gint qof_event_register_handler(QofEventHandler handler, gpointer user_data)
Register a handler for events.
The class data structure for a price tree model.
gint QofEventId
Define the type of events allowed.
gboolean gnc_tree_model_price_iter_is_commodity(GncTreeModelPrice *model, GtkTreeIter *iter)
Determine whether or not the specified GtkTreeIter points to a commodity.
void qof_event_unregister_handler(gint handler_id)
Unregister an event handler.
#define MAX_DATE_LENGTH
The maximum length of a string created by the date printers.
gboolean gnc_tree_model_price_iter_is_price(GncTreeModelPrice *model, GtkTreeIter *iter)
Determine whether or not the specified GtkTreeIter points to a price.
All type declarations for the whole Gnucash engine.
gboolean gnc_pricedb_has_prices(GNCPriceDB *db, const gnc_commodity *commodity, const gnc_commodity *currency)
Report whether the pricedb contains prices for one commodity in another.
const char * gnc_commodity_get_printname(const gnc_commodity *cm)
Retrieve the 'print' name for the specified commodity.
GtkTreeModel * gnc_tree_model_price_new(QofBook *book, GNCPriceDB *price_db)
Create a new GtkTreeModel for manipulating gnucash commodity prices.
GtkTreePath * gnc_tree_model_price_get_path_from_price(GncTreeModelPrice *model, GNCPrice *price)
Convert a price pointer into a GtkTreePath.
gnc_commodity_namespace * gnc_commodity_get_namespace_ds(const gnc_commodity *cm)
Retrieve the namespace data structure for the specified commodity.
#define LEAVE(format, args...)
Print a function exit debugging message.
gpointer qof_book_get_data(const QofBook *book, const gchar *key)
Retrieves arbitrary pointers to structs stored by qof_book_set_data.
GList * gnc_commodity_table_get_namespaces_list(const gnc_commodity_table *table)
Return a list of all namespace data structures in the commodity table.
The instance data structure for a price tree model.
size_t qof_print_date_buff(char *buff, size_t buflen, time64 secs)
Convenience: calls through to qof_print_date_dmy_buff().
gboolean gnc_tree_model_price_get_iter_from_commodity(GncTreeModelPrice *model, gnc_commodity *commodity, GtkTreeIter *iter)
Convert a commodity pointer into a GtkTreeIter.
PriceList * gnc_pricedb_get_prices(GNCPriceDB *db, const gnc_commodity *commodity, const gnc_commodity *currency)
Return all the prices for a given commodity in another.