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;
85 static void gnc_tree_model_price_finalize (GObject *
object);
86 static void gnc_tree_model_price_dispose (GObject *
object);
88 static void gnc_tree_model_price_tree_model_init (GtkTreeModelIface *iface);
89 static guint gnc_tree_model_price_get_flags (GtkTreeModel *tree_model);
90 static int gnc_tree_model_price_get_n_columns (GtkTreeModel *tree_model);
91 static GType gnc_tree_model_price_get_column_type (GtkTreeModel *tree_model,
93 static gboolean gnc_tree_model_price_get_iter (GtkTreeModel *tree_model,
96 static GtkTreePath *gnc_tree_model_price_get_path (GtkTreeModel *tree_model,
98 static void gnc_tree_model_price_get_value (GtkTreeModel *tree_model,
102 static gboolean gnc_tree_model_price_iter_next (GtkTreeModel *tree_model,
104 static gboolean gnc_tree_model_price_iter_children (GtkTreeModel *tree_model,
106 GtkTreeIter *parent);
107 static gboolean gnc_tree_model_price_iter_has_child (GtkTreeModel *tree_model,
109 static int gnc_tree_model_price_iter_n_children (GtkTreeModel *tree_model,
111 static gboolean gnc_tree_model_price_iter_nth_child (GtkTreeModel *tree_model,
115 static gboolean gnc_tree_model_price_iter_parent (GtkTreeModel *tree_model,
118 static void gnc_tree_model_price_event_handler (
QofInstance *entity,
121 gpointer event_data);
130 GNCPriceDB *price_db;
131 gint event_handler_id;
136 G_IMPLEMENT_INTERFACE(GTK_TYPE_TREE_MODEL,
137 gnc_tree_model_price_tree_model_init))
140 gnc_tree_model_price_class_init (GncTreeModelPriceClass *klass)
142 GObjectClass *o_class = G_OBJECT_CLASS (klass);
144 o_class->finalize = gnc_tree_model_price_finalize;
145 o_class->dispose = gnc_tree_model_price_dispose;
149 gnc_tree_model_price_init (GncTreeModelPrice *model)
151 while (model->stamp == 0)
153 model->stamp = g_random_int ();
156 model->print_info = gnc_default_price_print_info(NULL);
160 gnc_tree_model_price_finalize (GObject *
object)
162 GncTreeModelPrice *model;
164 ENTER(
"model %p",
object);
166 g_return_if_fail (
object != NULL);
167 g_return_if_fail (GNC_IS_TREE_MODEL_PRICE (
object));
169 model = GNC_TREE_MODEL_PRICE (
object);
172 model->price_db = NULL;
174 G_OBJECT_CLASS (gnc_tree_model_price_parent_class)->finalize (
object);
179 gnc_tree_model_price_dispose (GObject *
object)
181 GncTreeModelPrice *model;
183 ENTER(
"model %p",
object);
184 g_return_if_fail (
object != NULL);
185 g_return_if_fail (GNC_IS_TREE_MODEL_PRICE (
object));
187 model = GNC_TREE_MODEL_PRICE (
object);
189 if (model->event_handler_id)
192 model->event_handler_id = 0;
195 G_OBJECT_CLASS (gnc_tree_model_price_parent_class)->dispose (
object);
202 GncTreeModelPrice *model;
208 for ( ; item; item = g_list_next(item))
210 model = (GncTreeModelPrice *)item->data;
211 if (model->price_db == price_db)
213 g_object_ref(G_OBJECT(model));
214 LEAVE(
"returning existing model %p", model);
215 return GTK_TREE_MODEL(model);
219 model = g_object_new (GNC_TYPE_TREE_MODEL_PRICE, NULL);
222 model->price_db = price_db;
224 model->event_handler_id =
227 LEAVE(
"returning new model %p", model);
228 return GTK_TREE_MODEL (model);
235 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
236 g_return_val_if_fail (iter != NULL, FALSE);
237 g_return_val_if_fail (iter->user_data != NULL, FALSE);
238 g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
240 return (iter->user_data == ITER_IS_NAMESPACE);
247 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
248 g_return_val_if_fail (iter != NULL, FALSE);
249 g_return_val_if_fail (iter->user_data != NULL, FALSE);
250 g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
252 return (iter->user_data == ITER_IS_COMMODITY);
259 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
260 g_return_val_if_fail (iter != NULL, FALSE);
261 g_return_val_if_fail (iter->user_data != NULL, FALSE);
262 g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
264 return (iter->user_data == ITER_IS_PRICE);
267 gnc_commodity_namespace *
271 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), NULL);
272 g_return_val_if_fail (iter != NULL, NULL);
273 g_return_val_if_fail (iter->user_data != NULL, NULL);
274 g_return_val_if_fail (iter->stamp == model->stamp, NULL);
276 if (iter->user_data != ITER_IS_NAMESPACE)
278 return (gnc_commodity_namespace *)iter->user_data2;
285 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), NULL);
286 g_return_val_if_fail (iter != NULL, NULL);
287 g_return_val_if_fail (iter->user_data != NULL, NULL);
288 g_return_val_if_fail (iter->stamp == model->stamp, NULL);
290 if (iter->user_data != ITER_IS_COMMODITY)
292 return (gnc_commodity *)iter->user_data2;
299 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), NULL);
300 g_return_val_if_fail (iter != NULL, NULL);
301 g_return_val_if_fail (iter->user_data != NULL, NULL);
302 g_return_val_if_fail (iter->stamp == model->stamp, NULL);
304 if (iter->user_data != ITER_IS_PRICE)
306 return (GNCPrice *)iter->user_data2;
313 #define debug_path(fn, path) { \ 314 gchar *path_string = gtk_tree_path_to_string(path); \ 315 fn("tree path %s", path_string? path_string : "(NULL)"); \ 316 g_free(path_string); \ 319 #define ITER_STRING_LEN 256 322 iter_to_string (GncTreeModelPrice *model, GtkTreeIter *iter)
324 gnc_commodity_namespace *name_space;
325 gnc_commodity *commodity;
327 #ifdef G_THREADS_ENABLED 328 static GPrivate gtmits_buffer_key = G_PRIVATE_INIT(g_free);
331 string = g_private_get (>mits_buffer_key);
334 string = g_malloc(ITER_STRING_LEN + 1);
335 g_private_set (>mits_buffer_key,
string);
338 static char string[ITER_STRING_LEN + 1];
343 switch (GPOINTER_TO_INT(iter->user_data))
345 case GPOINTER_TO_INT(ITER_IS_NAMESPACE):
346 name_space = (gnc_commodity_namespace *) iter->user_data2;
347 snprintf(
string, ITER_STRING_LEN,
348 "[stamp:%x data:%d (NAMESPACE), %p (%s), %d]",
349 iter->stamp, GPOINTER_TO_INT(iter->user_data),
351 GPOINTER_TO_INT(iter->user_data3));
354 case GPOINTER_TO_INT(ITER_IS_COMMODITY):
355 commodity = (gnc_commodity *) iter->user_data2;
356 snprintf(
string, ITER_STRING_LEN,
357 "[stamp:%x data:%d (COMMODITY), %p (%s), %d]",
358 iter->stamp, GPOINTER_TO_INT(iter->user_data),
360 GPOINTER_TO_INT(iter->user_data3));
363 case GPOINTER_TO_INT(ITER_IS_PRICE):
364 price = (GNCPrice *) iter->user_data2;
365 commodity = gnc_price_get_commodity(price);
366 snprintf(
string, ITER_STRING_LEN,
367 "[stamp:%x data:%d (PRICE), %p (%s:%s), %d]",
368 iter->stamp, GPOINTER_TO_INT(iter->user_data),
371 GPOINTER_TO_INT(iter->user_data3));
375 snprintf(
string, ITER_STRING_LEN,
376 "[stamp:%x data:%d (UNKNOWN), %p, %d]",
378 GPOINTER_TO_INT(iter->user_data),
380 GPOINTER_TO_INT(iter->user_data3));
393 gnc_tree_model_price_tree_model_init (GtkTreeModelIface *iface)
395 iface->get_flags = gnc_tree_model_price_get_flags;
396 iface->get_n_columns = gnc_tree_model_price_get_n_columns;
397 iface->get_column_type = gnc_tree_model_price_get_column_type;
398 iface->get_iter = gnc_tree_model_price_get_iter;
399 iface->get_path = gnc_tree_model_price_get_path;
400 iface->get_value = gnc_tree_model_price_get_value;
401 iface->iter_next = gnc_tree_model_price_iter_next;
402 iface->iter_children = gnc_tree_model_price_iter_children;
403 iface->iter_has_child = gnc_tree_model_price_iter_has_child;
404 iface->iter_n_children = gnc_tree_model_price_iter_n_children;
405 iface->iter_nth_child = gnc_tree_model_price_iter_nth_child;
406 iface->iter_parent = gnc_tree_model_price_iter_parent;
410 gnc_tree_model_price_get_flags (GtkTreeModel *tree_model)
416 gnc_tree_model_price_get_n_columns (GtkTreeModel *tree_model)
418 return GNC_TREE_MODEL_PRICE_NUM_COLUMNS;
422 gnc_tree_model_price_get_column_type (GtkTreeModel *tree_model,
425 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), G_TYPE_INVALID);
426 g_return_val_if_fail ((index < GNC_TREE_MODEL_PRICE_NUM_COLUMNS) && (index >= 0), G_TYPE_INVALID);
430 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
431 case GNC_TREE_MODEL_PRICE_COL_CURRENCY:
432 case GNC_TREE_MODEL_PRICE_COL_DATE:
433 case GNC_TREE_MODEL_PRICE_COL_SOURCE:
434 case GNC_TREE_MODEL_PRICE_COL_TYPE:
435 case GNC_TREE_MODEL_PRICE_COL_VALUE:
436 return G_TYPE_STRING;
437 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
438 return G_TYPE_BOOLEAN;
440 g_assert_not_reached ();
441 return G_TYPE_INVALID;
446 gnc_tree_model_price_get_iter (GtkTreeModel *tree_model,
450 GncTreeModelPrice *model;
451 gnc_commodity_table *ct;
452 gnc_commodity_namespace *name_space;
453 gnc_commodity *commodity = NULL;
455 GList *ns_list, *cm_list;
458 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), FALSE);
460 depth = gtk_tree_path_get_depth (path);
461 ENTER(
"model %p, iter %p, path %p (depth %d)", tree_model, iter, path, depth);
462 debug_path(
DEBUG, path);
467 LEAVE(
"depth too small");
472 LEAVE(
"depth too big");
477 model = GNC_TREE_MODEL_PRICE (tree_model);
478 if (model->price_db == NULL)
480 LEAVE(
"no price db");
487 i = gtk_tree_path_get_indices (path)[0];
488 name_space = g_list_nth_data (ns_list, i);
491 LEAVE(
"invalid path at namespace");
494 g_list_free (ns_list);
499 iter->stamp = model->stamp;
500 iter->user_data = ITER_IS_NAMESPACE;
501 iter->user_data2 = name_space;
502 iter->user_data3 = GINT_TO_POINTER(i);
503 LEAVE(
"iter (ns) %s", iter_to_string(model, iter));
509 i = gtk_tree_path_get_indices (path)[1];
510 commodity = g_list_nth_data (cm_list, i);
511 g_list_free (cm_list);
514 LEAVE(
"invalid path at commodity");
521 iter->stamp = model->stamp;
522 iter->user_data = ITER_IS_COMMODITY;
523 iter->user_data2 = commodity;
524 iter->user_data3 = GINT_TO_POINTER(i);
525 LEAVE(
"iter (cm) %s", iter_to_string(model, iter));
530 i = gtk_tree_path_get_indices (path)[2];
535 #ifdef RACE_CONDITION_SOLVED 538 LEAVE(
"invalid path at price");
544 iter->stamp = model->stamp;
545 iter->user_data = ITER_IS_PRICE;
546 iter->user_data2 = price;
547 iter->user_data3 = GINT_TO_POINTER(i);
548 LEAVE(
"iter (pc) %s", iter_to_string(model, iter));
553 gnc_tree_model_price_get_path (GtkTreeModel *tree_model,
556 GncTreeModelPrice *model = GNC_TREE_MODEL_PRICE (tree_model);
557 gnc_commodity_table *ct;
558 gnc_commodity_namespace *name_space;
559 gnc_commodity *commodity;
560 GList *ns_list, *cm_list;
563 ENTER(
"model %p, iter %p (%s)", tree_model, iter, iter_to_string(model, iter));
564 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), NULL);
565 g_return_val_if_fail (iter != NULL, NULL);
566 g_return_val_if_fail (iter->user_data != NULL, NULL);
567 g_return_val_if_fail (iter->stamp == model->stamp, NULL);
570 if (model->price_db == NULL)
572 LEAVE(
"no price db");
576 if (iter->user_data == ITER_IS_NAMESPACE)
580 path = gtk_tree_path_new ();
581 gtk_tree_path_append_index (path, GPOINTER_TO_INT(iter->user_data3));
582 debug_path(
LEAVE, path);
590 if (iter->user_data == ITER_IS_COMMODITY)
593 commodity = (gnc_commodity*)iter->user_data2;
595 path = gtk_tree_path_new ();
596 gtk_tree_path_append_index (path, g_list_index (ns_list, name_space));
597 gtk_tree_path_append_index (path, GPOINTER_TO_INT(iter->user_data3));
598 debug_path(
LEAVE, path);
599 g_list_free (ns_list);
604 commodity = gnc_price_get_commodity((GNCPrice*)iter->user_data2);
607 path = gtk_tree_path_new ();
608 gtk_tree_path_append_index (path, g_list_index (ns_list, name_space));
609 gtk_tree_path_append_index (path, g_list_index (cm_list, commodity));
610 gtk_tree_path_append_index (path, GPOINTER_TO_INT(iter->user_data3));
611 debug_path(
LEAVE, path);
612 g_list_free (cm_list);
613 g_list_free (ns_list);
618 gnc_tree_model_price_get_value (GtkTreeModel *tree_model,
623 GncTreeModelPrice *model = GNC_TREE_MODEL_PRICE (tree_model);
624 gnc_commodity_namespace *name_space;
625 gnc_commodity *commodity;
628 memset (datebuff, 0,
sizeof(datebuff));
630 g_return_if_fail (GNC_IS_TREE_MODEL_PRICE (model));
631 g_return_if_fail (iter != NULL);
632 #ifdef RACE_CONDITION_SOLVED 633 g_return_if_fail (iter->user_data != NULL);
635 g_return_if_fail (iter->stamp == model->stamp);
637 if (iter->user_data == ITER_IS_NAMESPACE)
639 name_space = (gnc_commodity_namespace *)iter->user_data2;
642 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
643 g_value_init (value, G_TYPE_STRING);
646 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
647 g_value_init (value, G_TYPE_BOOLEAN);
648 g_value_set_boolean (value, FALSE);
651 g_value_init (value, G_TYPE_STRING);
652 g_value_set_string (value,
"");
658 if (iter->user_data == ITER_IS_COMMODITY)
660 commodity = (gnc_commodity *)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 price = (GNCPrice *)iter->user_data2;
680 #ifdef RACE_CONDITION_SOLVED
681 g_return_if_fail (price != NULL);
687 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
688 g_value_init (value, G_TYPE_STRING);
689 g_value_set_string (value,
"");
691 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
692 g_value_init (value, G_TYPE_BOOLEAN);
693 g_value_set_boolean (value, FALSE);
696 g_value_init (value, G_TYPE_STRING);
697 g_value_set_string (value,
"");
706 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
707 g_value_init (value, G_TYPE_STRING);
708 commodity = gnc_price_get_commodity (price);
711 case GNC_TREE_MODEL_PRICE_COL_CURRENCY:
712 g_value_init (value, G_TYPE_STRING);
713 commodity = gnc_price_get_currency (price);
716 case GNC_TREE_MODEL_PRICE_COL_DATE:
718 gnc_price_get_time64 (price));
719 g_value_init (value, G_TYPE_STRING);
720 g_value_set_string (value, datebuff);
722 case GNC_TREE_MODEL_PRICE_COL_SOURCE:
723 g_value_init (value, G_TYPE_STRING);
724 g_value_set_string (value, gettext (gnc_price_get_source_string (price)));
726 case GNC_TREE_MODEL_PRICE_COL_TYPE:
727 g_value_init (value, G_TYPE_STRING);
728 g_value_set_string (value, gnc_price_get_typestr (price));
730 case GNC_TREE_MODEL_PRICE_COL_VALUE:
731 g_value_init (value, G_TYPE_STRING);
732 g_value_set_string (value,
xaccPrintAmount (gnc_price_get_value (price),
735 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
736 g_value_init (value, G_TYPE_BOOLEAN);
737 g_value_set_boolean (value, TRUE);
740 g_assert_not_reached ();
745 gnc_tree_model_price_iter_next (GtkTreeModel *tree_model,
748 GncTreeModelPrice *model = GNC_TREE_MODEL_PRICE (tree_model);
749 gnc_commodity_table *ct;
750 gnc_commodity *commodity;
751 gnc_commodity_namespace *name_space;
755 ENTER(
"model %p, iter %p(%s)", tree_model, iter, iter_to_string(model, iter));
756 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
757 g_return_val_if_fail (iter != NULL, FALSE);
758 g_return_val_if_fail (iter->user_data != NULL, FALSE);
759 g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
761 if (iter->user_data == ITER_IS_NAMESPACE)
765 n = GPOINTER_TO_INT(iter->user_data3) + 1;
766 iter->user_data2 = g_list_nth_data(list, n);
768 if (iter->user_data2 == NULL)
770 LEAVE(
"no next iter");
773 iter->user_data3 = GINT_TO_POINTER(n);
774 LEAVE(
"iter %p(%s)", iter, iter_to_string(model, iter));
777 else if (iter->user_data == ITER_IS_COMMODITY)
781 n = GPOINTER_TO_INT(iter->user_data3) + 1;
782 iter->user_data2 = g_list_nth_data(list, n);
784 if (iter->user_data2 == NULL)
786 LEAVE(
"no next iter");
789 iter->user_data3 = GINT_TO_POINTER(n);
790 LEAVE(
"iter %p(%s)", iter, iter_to_string(model, iter));
793 else if (iter->user_data == ITER_IS_PRICE)
795 commodity = gnc_price_get_commodity((GNCPrice*)iter->user_data2);
796 n = GPOINTER_TO_INT(iter->user_data3) + 1;
798 if (iter->user_data2 == NULL)
800 LEAVE(
"no next iter");
803 iter->user_data3 = GINT_TO_POINTER(n);
804 LEAVE(
"iter %p(%s)", iter, iter_to_string(model, iter));
809 LEAVE(
"unknown iter type");
815 gnc_tree_model_price_iter_children (GtkTreeModel *tree_model,
819 GncTreeModelPrice *model;
820 gnc_commodity_table *ct;
821 gnc_commodity_namespace *name_space;
822 gnc_commodity *commodity;
825 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), FALSE);
827 model = GNC_TREE_MODEL_PRICE (tree_model);
828 ENTER(
"model %p, iter %p, parent %p (%s)",
829 tree_model, iter, parent, iter_to_string(model, parent));
837 LEAVE(
"no namespaces");
841 iter->stamp = model->stamp;
842 iter->user_data = ITER_IS_NAMESPACE;
843 iter->user_data2 = g_list_nth_data(list, 0);
844 iter->user_data3 = GINT_TO_POINTER(0);
845 LEAVE(
"ns iter %p (%s)", iter, iter_to_string(model, iter));
850 if (parent->user_data == ITER_IS_NAMESPACE)
852 name_space = (gnc_commodity_namespace *)parent->user_data2;
856 LEAVE(
"no commodities");
860 iter->stamp = model->stamp;
861 iter->user_data = ITER_IS_COMMODITY;
862 iter->user_data2 = g_list_nth_data(list, 0);
863 iter->user_data3 = GINT_TO_POINTER(0);
864 LEAVE(
"cm iter %p (%s)", iter, iter_to_string(model, iter));
869 if (parent->user_data == ITER_IS_COMMODITY)
872 commodity = (gnc_commodity *)parent->user_data2;
879 iter->stamp = model->stamp;
880 iter->user_data = ITER_IS_PRICE;
881 iter->user_data2 = price;
882 iter->user_data3 = GINT_TO_POINTER(0);
883 LEAVE(
"price iter %p (%s)", iter, iter_to_string(model, iter));
892 gnc_tree_model_price_iter_has_child (GtkTreeModel *tree_model,
895 GncTreeModelPrice *model;
896 gnc_commodity_namespace *name_space;
897 gnc_commodity *commodity;
901 model = GNC_TREE_MODEL_PRICE (tree_model);
902 ENTER(
"model %p, iter %p (%s)", tree_model,
903 iter, iter_to_string(model, iter));
904 g_return_val_if_fail (tree_model != NULL, FALSE);
905 g_return_val_if_fail (iter != NULL, FALSE);
907 if (iter->user_data == ITER_IS_PRICE)
909 LEAVE(
"price has no children");
913 if (iter->user_data == ITER_IS_NAMESPACE)
915 name_space = (gnc_commodity_namespace *)iter->user_data2;
917 LEAVE(
"%s children", list ?
"has" :
"no");
918 gboolean rv = (list != NULL);
923 if (iter->user_data == ITER_IS_COMMODITY)
925 commodity = (gnc_commodity *)iter->user_data2;
927 LEAVE(
"%s children", result ?
"has" :
"no");
931 LEAVE(
"no children (unknown type)");
936 gnc_tree_model_price_iter_n_children (GtkTreeModel *tree_model,
939 GncTreeModelPrice *model;
940 gnc_commodity_table *ct;
941 gnc_commodity_namespace *name_space;
942 gnc_commodity *commodity;
946 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), -1);
948 model = GNC_TREE_MODEL_PRICE (tree_model);
949 ENTER(
"model %p, iter %p (%s)", tree_model, iter,
950 iter_to_string(model, iter));
956 LEAVE(
"ns list length %d", g_list_length(list));
957 guint rv = g_list_length (list);
962 if (iter->user_data == ITER_IS_NAMESPACE)
964 name_space = (gnc_commodity_namespace *)iter->user_data2;
966 LEAVE(
"cm list length %d", g_list_length(list));
967 guint rv = g_list_length (list);
972 if (iter->user_data == ITER_IS_COMMODITY)
974 commodity = (gnc_commodity *)iter->user_data2;
976 LEAVE(
"price list length %d", n);
985 gnc_tree_model_price_iter_nth_child (GtkTreeModel *tree_model,
990 GncTreeModelPrice *model;
991 gnc_commodity_table *ct;
992 gnc_commodity_namespace *name_space;
993 gnc_commodity *commodity;
996 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), FALSE);
997 g_return_val_if_fail (iter != NULL, FALSE);
999 model = GNC_TREE_MODEL_PRICE (tree_model);
1000 ENTER(
"model %p, iter %p, parent %p (%s), n %d",
1001 tree_model, iter, parent, iter_to_string(model, parent), n);
1008 iter->stamp = model->stamp;
1009 iter->user_data = ITER_IS_NAMESPACE;
1010 iter->user_data2 = g_list_nth_data(list, n);
1011 iter->user_data3 = GINT_TO_POINTER(n);
1012 LEAVE(
"ns iter %p (%s)", iter, iter_to_string(model, iter));
1014 return iter->user_data2 != NULL;
1017 if (parent->user_data == ITER_IS_NAMESPACE)
1019 name_space = (gnc_commodity_namespace *)parent->user_data2;
1022 iter->stamp = model->stamp;
1023 iter->user_data = ITER_IS_COMMODITY;
1024 iter->user_data2 = g_list_nth_data(list, n);
1025 iter->user_data3 = GINT_TO_POINTER(n);
1026 LEAVE(
"cm iter %p (%s)", iter, iter_to_string(model, iter));
1028 return iter->user_data2 != NULL;
1031 if (parent->user_data == ITER_IS_COMMODITY)
1033 commodity = (gnc_commodity *)parent->user_data2;
1035 iter->stamp = model->stamp;
1036 iter->user_data = ITER_IS_PRICE;
1038 iter->user_data3 = GINT_TO_POINTER(n);
1039 LEAVE(
"price iter %p (%s)", iter, iter_to_string(model, iter));
1040 return iter->user_data2 != NULL;
1049 gnc_tree_model_price_iter_parent (GtkTreeModel *tree_model,
1053 GncTreeModelPrice *model;
1054 gnc_commodity_table *ct;
1055 gnc_commodity * commodity;
1056 gnc_commodity_namespace *name_space;
1059 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), FALSE);
1060 g_return_val_if_fail (iter != NULL, FALSE);
1061 g_return_val_if_fail (child != NULL, FALSE);
1063 model = GNC_TREE_MODEL_PRICE (tree_model);
1064 ENTER(
"model %p, iter %p, child %p (%s)",
1065 tree_model, iter, child, iter_to_string(model, child));
1067 if (child->user_data == ITER_IS_NAMESPACE)
1069 LEAVE(
"ns has no parent");
1073 if (child->user_data == ITER_IS_COMMODITY)
1079 iter->stamp = model->stamp;
1080 iter->user_data = ITER_IS_NAMESPACE;
1081 iter->user_data2 = name_space;
1082 iter->user_data3 = GINT_TO_POINTER(g_list_index(list, name_space));
1083 LEAVE(
"ns iter %p (%s)", iter, iter_to_string(model, iter));
1088 commodity = gnc_price_get_commodity ((GNCPrice*)child->user_data2);
1092 iter->stamp = model->stamp;
1093 iter->user_data = ITER_IS_COMMODITY;
1094 iter->user_data2 = commodity;
1095 iter->user_data3 = GINT_TO_POINTER(g_list_index(list, commodity));
1096 LEAVE(
"cm iter %p (%s)", iter, iter_to_string(model, iter));
1115 gnc_commodity *commodity;
1119 ENTER(
"model %p, price %p, iter %p", model, price, iter);
1120 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
1121 g_return_val_if_fail ((price != NULL), FALSE);
1122 g_return_val_if_fail ((iter != NULL), FALSE);
1124 commodity = gnc_price_get_commodity(price);
1125 if (commodity == NULL)
1127 LEAVE(
"no commodity");
1134 LEAVE(
"empty list");
1138 n = g_list_index(list, price);
1142 LEAVE(
"not in list");
1146 iter->stamp = model->stamp;
1147 iter->user_data = ITER_IS_PRICE;
1148 iter->user_data2 = price;
1149 iter->user_data3 = GINT_TO_POINTER(n);
1151 LEAVE(
"iter %s", iter_to_string(model, iter));
1164 GtkTreeIter tree_iter;
1165 GtkTreePath *tree_path;
1167 ENTER(
"model %p, price %p", model, price);
1168 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), NULL);
1169 g_return_val_if_fail (price != NULL, NULL);
1177 tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &tree_iter);
1180 gchar *path_string = gtk_tree_path_to_string(tree_path);
1181 LEAVE(
"path (2) %s", path_string);
1182 g_free(path_string);
1198 gnc_commodity *commodity,
1201 gnc_commodity_namespace *name_space;
1205 ENTER(
"model %p, commodity %p, iter %p", model, commodity, iter);
1206 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
1207 g_return_val_if_fail ((commodity != NULL), FALSE);
1208 g_return_val_if_fail ((iter != NULL), FALSE);
1211 if (name_space == NULL)
1213 LEAVE(
"no namespace");
1220 LEAVE(
"empty list");
1224 n = g_list_index(list, commodity);
1228 LEAVE(
"commodity not in list");
1232 iter->stamp = model->stamp;
1233 iter->user_data = ITER_IS_COMMODITY;
1234 iter->user_data2 = commodity;
1235 iter->user_data3 = GINT_TO_POINTER(n);
1236 LEAVE(
"iter %s", iter_to_string(model, iter));
1247 gnc_commodity_namespace *name_space,
1250 gnc_commodity_table *ct;
1254 ENTER(
"model %p, namespace %p, iter %p", model, name_space, iter);
1255 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
1256 g_return_val_if_fail ((name_space != NULL), FALSE);
1257 g_return_val_if_fail ((iter != NULL), FALSE);
1263 LEAVE(
"namespace list empty");
1267 n = g_list_index(list, name_space);
1271 LEAVE(
"namespace not found");
1275 iter->stamp = model->stamp;
1276 iter->user_data = ITER_IS_NAMESPACE;
1277 iter->user_data2 = name_space;
1278 iter->user_data3 = GINT_TO_POINTER(n);
1279 LEAVE(
"iter %s", iter_to_string(model, iter));
1287 typedef struct _remove_data
1289 GncTreeModelPrice *model;
1293 static GSList *pending_removals = NULL;
1307 gnc_tree_model_price_row_add (GncTreeModelPrice *model,
1311 GtkTreeModel *tree_model;
1312 GtkTreeIter tmp_iter;
1314 ENTER(
"model %p, iter (%p)%s", model, iter, iter_to_string(model, iter));
1324 while (model->stamp == 0);
1325 iter->stamp = model->stamp;
1328 tree_model = GTK_TREE_MODEL(model);
1329 path = gnc_tree_model_price_get_path (tree_model, iter);
1330 gtk_tree_model_row_inserted (tree_model, path, iter);
1337 if (gtk_tree_path_up(path) &&
1338 gtk_tree_path_get_depth(path) > 0 &&
1339 gtk_tree_model_get_iter(tree_model, &tmp_iter, path))
1342 gtk_tree_model_row_changed(tree_model, path, &tmp_iter);
1345 if (gtk_tree_model_iter_n_children(tree_model, &tmp_iter) == 1)
1346 gtk_tree_model_row_has_child_toggled(tree_model, path, &tmp_iter);
1349 while (gtk_tree_path_up(path) &&
1350 gtk_tree_path_get_depth(path) > 0 &&
1351 gtk_tree_model_get_iter(tree_model, &tmp_iter, path))
1353 gtk_tree_model_row_changed(tree_model, path, &tmp_iter);
1356 gtk_tree_path_free(path);
1362 if (gnc_tree_model_price_iter_has_child(tree_model, iter))
1364 path = gnc_tree_model_price_get_path(tree_model, iter);
1365 gtk_tree_model_row_has_child_toggled(tree_model, path, iter);
1366 gtk_tree_path_free(path);
1384 gnc_tree_model_price_row_delete (GncTreeModelPrice *model,
1387 GtkTreeModel *tree_model;
1390 g_return_if_fail(GNC_IS_TREE_MODEL_PRICE(model));
1391 g_return_if_fail(path);
1393 debug_path(
ENTER, path);
1395 tree_model = GTK_TREE_MODEL(model);
1405 while (model->stamp == 0);
1408 gtk_tree_model_row_deleted(tree_model, path);
1411 if (gtk_tree_path_up(path) &&
1412 gtk_tree_path_get_depth(path) > 0 &&
1413 gtk_tree_model_get_iter(tree_model, &iter, path))
1415 DEBUG(
"iter %s", iter_to_string(model, &iter));
1418 gtk_tree_model_row_changed(tree_model, path, &iter);
1421 if (!gtk_tree_model_iter_has_child(tree_model, &iter))
1422 gtk_tree_model_row_has_child_toggled(tree_model, path, &iter);
1425 while (gtk_tree_path_up(path) &&
1426 gtk_tree_path_get_depth(path) > 0 &&
1427 gtk_tree_model_get_iter(tree_model, &iter, path))
1429 DEBUG(
"iter %s", iter_to_string(model, &iter));
1430 gtk_tree_model_row_changed(tree_model, path, &iter);
1455 gnc_tree_model_price_do_deletions (gpointer price_db)
1460 while (pending_removals)
1463 pending_removals = g_slist_delete_link(pending_removals, pending_removals);
1467 debug_path(
DEBUG, data->path);
1470 gnc_tree_model_price_row_delete(data->model, data->path);
1471 gnc_pricedb_nth_price_reset_cache (price_db);
1473 gtk_tree_path_free(data->path);
1516 gnc_tree_model_price_event_handler (
QofInstance *entity,
1519 gpointer event_data)
1521 GncTreeModelPrice *model;
1527 ENTER(
"entity %p, event %d, model %p, event data %p",
1528 entity, event_type, user_data, event_data);
1529 model = (GncTreeModelPrice *)user_data;
1532 if (pending_removals)
1533 gnc_tree_model_price_do_deletions (model->price_db);
1536 g_return_if_fail(GNC_IS_TREE_MODEL_PRICE(model));
1539 if (GNC_IS_COMMODITY(entity))
1541 gnc_commodity *commodity;
1543 commodity = GNC_COMMODITY(entity);
1545 if (event_type != QOF_EVENT_DESTROY)
1554 else if (GNC_IS_COMMODITY_NAMESPACE(entity))
1556 gnc_commodity_namespace *name_space;
1558 name_space = GNC_COMMODITY_NAMESPACE(entity);
1560 if (event_type != QOF_EVENT_DESTROY)
1569 else if (GNC_IS_PRICE(entity))
1573 price = GNC_PRICE(entity);
1575 if (event_type != QOF_EVENT_DESTROY)
1594 DEBUG(
"add %s", name);
1595 gnc_pricedb_nth_price_reset_cache (model->price_db);
1596 gnc_tree_model_price_row_add (model, &iter);
1599 case QOF_EVENT_REMOVE:
1601 DEBUG(
"remove %s", name);
1602 path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter);
1605 LEAVE(
"not in model");
1610 data->model = model;
1612 pending_removals = g_slist_append (pending_removals, data);
1613 g_idle_add_full(G_PRIORITY_HIGH_IDLE,
1614 gnc_tree_model_price_do_deletions, model->price_db, NULL);
1619 case QOF_EVENT_MODIFY:
1620 DEBUG(
"change %s", name);
1621 path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter);
1624 LEAVE(
"not in model");
1627 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &iter, path))
1629 gtk_tree_path_free(path);
1630 LEAVE(
"can't find iter for path");
1633 gtk_tree_model_row_changed(GTK_TREE_MODEL(model), path, &iter);
1634 gtk_tree_path_free(path);
1639 LEAVE(
"ignored event for %s", name);
1642 LEAVE(
" new stamp %u", model->stamp);
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.
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.
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.
G_DEFINE_TYPE_WITH_CODE(GncMainWindow, gnc_main_window, GTK_TYPE_APPLICATION_WINDOW, G_IMPLEMENT_INTERFACE(GNC_TYPE_WINDOW, gnc_window_main_window_init)) static guint main_window_signals[LAST_SIGNAL]
A holding place for all the signals generated by the main window code.
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 instance 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.
GncTreeModel gnc_tree_model
The parent object data.
void qof_event_unregister_handler(gint handler_id)
Unregister an event handler.
int stamp
The state of the model.
#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.
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.