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");
498 iter->stamp = model->stamp;
499 iter->user_data = ITER_IS_NAMESPACE;
500 iter->user_data2 = name_space;
501 iter->user_data3 = GINT_TO_POINTER(i);
502 LEAVE(
"iter (ns) %s", iter_to_string(model, iter));
508 i = gtk_tree_path_get_indices (path)[1];
509 commodity = g_list_nth_data (cm_list, i);
512 LEAVE(
"invalid path at commodity");
519 iter->stamp = model->stamp;
520 iter->user_data = ITER_IS_COMMODITY;
521 iter->user_data2 = commodity;
522 iter->user_data3 = GINT_TO_POINTER(i);
523 LEAVE(
"iter (cm) %s", iter_to_string(model, iter));
528 i = gtk_tree_path_get_indices (path)[2];
533 #ifdef RACE_CONDITION_SOLVED 536 LEAVE(
"invalid path at price");
542 iter->stamp = model->stamp;
543 iter->user_data = ITER_IS_PRICE;
544 iter->user_data2 = price;
545 iter->user_data3 = GINT_TO_POINTER(i);
546 LEAVE(
"iter (pc) %s", iter_to_string(model, iter));
551 gnc_tree_model_price_get_path (GtkTreeModel *tree_model,
554 GncTreeModelPrice *model = GNC_TREE_MODEL_PRICE (tree_model);
555 gnc_commodity_table *ct;
556 gnc_commodity_namespace *name_space;
557 gnc_commodity *commodity;
558 GList *ns_list, *cm_list;
561 ENTER(
"model %p, iter %p (%s)", tree_model, iter, iter_to_string(model, iter));
562 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), NULL);
563 g_return_val_if_fail (iter != NULL, NULL);
564 g_return_val_if_fail (iter->user_data != NULL, NULL);
565 g_return_val_if_fail (iter->stamp == model->stamp, NULL);
568 if (model->price_db == NULL)
570 LEAVE(
"no price db");
574 if (iter->user_data == ITER_IS_NAMESPACE)
578 path = gtk_tree_path_new ();
579 gtk_tree_path_append_index (path, GPOINTER_TO_INT(iter->user_data3));
580 debug_path(
LEAVE, path);
588 if (iter->user_data == ITER_IS_COMMODITY)
591 commodity = (gnc_commodity*)iter->user_data2;
593 path = gtk_tree_path_new ();
594 gtk_tree_path_append_index (path, g_list_index (ns_list, name_space));
595 gtk_tree_path_append_index (path, GPOINTER_TO_INT(iter->user_data3));
596 debug_path(
LEAVE, path);
601 commodity = gnc_price_get_commodity((GNCPrice*)iter->user_data2);
604 path = gtk_tree_path_new ();
605 gtk_tree_path_append_index (path, g_list_index (ns_list, name_space));
606 gtk_tree_path_append_index (path, g_list_index (cm_list, commodity));
607 gtk_tree_path_append_index (path, GPOINTER_TO_INT(iter->user_data3));
608 debug_path(
LEAVE, path);
613 gnc_tree_model_price_get_value (GtkTreeModel *tree_model,
618 GncTreeModelPrice *model = GNC_TREE_MODEL_PRICE (tree_model);
619 gnc_commodity_namespace *name_space;
620 gnc_commodity *commodity;
623 memset (datebuff, 0,
sizeof(datebuff));
625 g_return_if_fail (GNC_IS_TREE_MODEL_PRICE (model));
626 g_return_if_fail (iter != NULL);
627 #ifdef RACE_CONDITION_SOLVED 628 g_return_if_fail (iter->user_data != NULL);
630 g_return_if_fail (iter->stamp == model->stamp);
632 if (iter->user_data == ITER_IS_NAMESPACE)
634 name_space = (gnc_commodity_namespace *)iter->user_data2;
637 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
638 g_value_init (value, G_TYPE_STRING);
641 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
642 g_value_init (value, G_TYPE_BOOLEAN);
643 g_value_set_boolean (value, FALSE);
646 g_value_init (value, G_TYPE_STRING);
647 g_value_set_string (value,
"");
653 if (iter->user_data == ITER_IS_COMMODITY)
655 commodity = (gnc_commodity *)iter->user_data2;
658 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
659 g_value_init (value, G_TYPE_STRING);
662 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
663 g_value_init (value, G_TYPE_BOOLEAN);
664 g_value_set_boolean (value, FALSE);
667 g_value_init (value, G_TYPE_STRING);
668 g_value_set_string (value,
"");
674 price = (GNCPrice *)iter->user_data2;
675 #ifdef RACE_CONDITION_SOLVED
676 g_return_if_fail (price != NULL);
682 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
683 g_value_init (value, G_TYPE_STRING);
684 g_value_set_string (value,
"");
686 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
687 g_value_init (value, G_TYPE_BOOLEAN);
688 g_value_set_boolean (value, FALSE);
691 g_value_init (value, G_TYPE_STRING);
692 g_value_set_string (value,
"");
701 case GNC_TREE_MODEL_PRICE_COL_COMMODITY:
702 g_value_init (value, G_TYPE_STRING);
703 commodity = gnc_price_get_commodity (price);
706 case GNC_TREE_MODEL_PRICE_COL_CURRENCY:
707 g_value_init (value, G_TYPE_STRING);
708 commodity = gnc_price_get_currency (price);
711 case GNC_TREE_MODEL_PRICE_COL_DATE:
713 gnc_price_get_time64 (price));
714 g_value_init (value, G_TYPE_STRING);
715 g_value_set_string (value, datebuff);
717 case GNC_TREE_MODEL_PRICE_COL_SOURCE:
718 g_value_init (value, G_TYPE_STRING);
719 g_value_set_string (value, gettext (gnc_price_get_source_string (price)));
721 case GNC_TREE_MODEL_PRICE_COL_TYPE:
722 g_value_init (value, G_TYPE_STRING);
723 g_value_set_string (value, gnc_price_get_typestr (price));
725 case GNC_TREE_MODEL_PRICE_COL_VALUE:
726 g_value_init (value, G_TYPE_STRING);
727 g_value_set_string (value,
xaccPrintAmount (gnc_price_get_value (price),
730 case GNC_TREE_MODEL_PRICE_COL_VISIBILITY:
731 g_value_init (value, G_TYPE_BOOLEAN);
732 g_value_set_boolean (value, TRUE);
735 g_assert_not_reached ();
740 gnc_tree_model_price_iter_next (GtkTreeModel *tree_model,
743 GncTreeModelPrice *model = GNC_TREE_MODEL_PRICE (tree_model);
744 gnc_commodity_table *ct;
745 gnc_commodity *commodity;
746 gnc_commodity_namespace *name_space;
750 ENTER(
"model %p, iter %p(%s)", tree_model, iter, iter_to_string(model, iter));
751 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
752 g_return_val_if_fail (iter != NULL, FALSE);
753 g_return_val_if_fail (iter->user_data != NULL, FALSE);
754 g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
756 if (iter->user_data == ITER_IS_NAMESPACE)
760 n = GPOINTER_TO_INT(iter->user_data3) + 1;
761 iter->user_data2 = g_list_nth_data(list, n);
762 if (iter->user_data2 == NULL)
764 LEAVE(
"no next iter");
767 iter->user_data3 = GINT_TO_POINTER(n);
768 LEAVE(
"iter %p(%s)", iter, iter_to_string(model, iter));
771 else if (iter->user_data == ITER_IS_COMMODITY)
775 n = GPOINTER_TO_INT(iter->user_data3) + 1;
776 iter->user_data2 = g_list_nth_data(list, n);
777 if (iter->user_data2 == NULL)
779 LEAVE(
"no next iter");
782 iter->user_data3 = GINT_TO_POINTER(n);
783 LEAVE(
"iter %p(%s)", iter, iter_to_string(model, iter));
786 else if (iter->user_data == ITER_IS_PRICE)
788 commodity = gnc_price_get_commodity((GNCPrice*)iter->user_data2);
789 n = GPOINTER_TO_INT(iter->user_data3) + 1;
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));
802 LEAVE(
"unknown iter type");
808 gnc_tree_model_price_iter_children (GtkTreeModel *tree_model,
812 GncTreeModelPrice *model;
813 gnc_commodity_table *ct;
814 gnc_commodity_namespace *name_space;
815 gnc_commodity *commodity;
818 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), FALSE);
820 model = GNC_TREE_MODEL_PRICE (tree_model);
821 ENTER(
"model %p, iter %p, parent %p (%s)",
822 tree_model, iter, parent, iter_to_string(model, parent));
830 LEAVE(
"no namespaces");
834 iter->stamp = model->stamp;
835 iter->user_data = ITER_IS_NAMESPACE;
836 iter->user_data2 = g_list_nth_data(list, 0);
837 iter->user_data3 = GINT_TO_POINTER(0);
838 LEAVE(
"ns iter %p (%s)", iter, iter_to_string(model, iter));
842 if (parent->user_data == ITER_IS_NAMESPACE)
844 name_space = (gnc_commodity_namespace *)parent->user_data2;
848 LEAVE(
"no commodities");
852 iter->stamp = model->stamp;
853 iter->user_data = ITER_IS_COMMODITY;
854 iter->user_data2 = g_list_nth_data(list, 0);
855 iter->user_data3 = GINT_TO_POINTER(0);
856 LEAVE(
"cm iter %p (%s)", iter, iter_to_string(model, iter));
860 if (parent->user_data == ITER_IS_COMMODITY)
863 commodity = (gnc_commodity *)parent->user_data2;
870 iter->stamp = model->stamp;
871 iter->user_data = ITER_IS_PRICE;
872 iter->user_data2 = price;
873 iter->user_data3 = GINT_TO_POINTER(0);
874 LEAVE(
"price iter %p (%s)", iter, iter_to_string(model, iter));
883 gnc_tree_model_price_iter_has_child (GtkTreeModel *tree_model,
886 GncTreeModelPrice *model;
887 gnc_commodity_namespace *name_space;
888 gnc_commodity *commodity;
892 model = GNC_TREE_MODEL_PRICE (tree_model);
893 ENTER(
"model %p, iter %p (%s)", tree_model,
894 iter, iter_to_string(model, iter));
895 g_return_val_if_fail (tree_model != NULL, FALSE);
896 g_return_val_if_fail (iter != NULL, FALSE);
898 if (iter->user_data == ITER_IS_PRICE)
900 LEAVE(
"price has no children");
904 if (iter->user_data == ITER_IS_NAMESPACE)
906 name_space = (gnc_commodity_namespace *)iter->user_data2;
908 LEAVE(
"%s children", list ?
"has" :
"no");
912 if (iter->user_data == ITER_IS_COMMODITY)
914 commodity = (gnc_commodity *)iter->user_data2;
916 LEAVE(
"%s children", result ?
"has" :
"no");
920 LEAVE(
"no children (unknown type)");
925 gnc_tree_model_price_iter_n_children (GtkTreeModel *tree_model,
928 GncTreeModelPrice *model;
929 gnc_commodity_table *ct;
930 gnc_commodity_namespace *name_space;
931 gnc_commodity *commodity;
935 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), -1);
937 model = GNC_TREE_MODEL_PRICE (tree_model);
938 ENTER(
"model %p, iter %p (%s)", tree_model, iter,
939 iter_to_string(model, iter));
945 LEAVE(
"ns list length %d", g_list_length(list));
946 return g_list_length (list);
949 if (iter->user_data == ITER_IS_NAMESPACE)
951 name_space = (gnc_commodity_namespace *)iter->user_data2;
953 LEAVE(
"cm list length %d", g_list_length(list));
954 return g_list_length (list);
957 if (iter->user_data == ITER_IS_COMMODITY)
959 commodity = (gnc_commodity *)iter->user_data2;
961 LEAVE(
"price list length %d", n);
970 gnc_tree_model_price_iter_nth_child (GtkTreeModel *tree_model,
975 GncTreeModelPrice *model;
976 gnc_commodity_table *ct;
977 gnc_commodity_namespace *name_space;
978 gnc_commodity *commodity;
981 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), FALSE);
982 g_return_val_if_fail (iter != NULL, FALSE);
984 model = GNC_TREE_MODEL_PRICE (tree_model);
985 ENTER(
"model %p, iter %p, parent %p (%s), n %d",
986 tree_model, iter, parent, iter_to_string(model, parent), n);
993 iter->stamp = model->stamp;
994 iter->user_data = ITER_IS_NAMESPACE;
995 iter->user_data2 = g_list_nth_data(list, n);
996 iter->user_data3 = GINT_TO_POINTER(n);
997 LEAVE(
"ns iter %p (%s)", iter, iter_to_string(model, iter));
998 return iter->user_data2 != NULL;
1001 if (parent->user_data == ITER_IS_NAMESPACE)
1003 name_space = (gnc_commodity_namespace *)parent->user_data2;
1006 iter->stamp = model->stamp;
1007 iter->user_data = ITER_IS_COMMODITY;
1008 iter->user_data2 = g_list_nth_data(list, n);
1009 iter->user_data3 = GINT_TO_POINTER(n);
1010 LEAVE(
"cm iter %p (%s)", iter, iter_to_string(model, iter));
1011 return iter->user_data2 != NULL;
1014 if (parent->user_data == ITER_IS_COMMODITY)
1016 commodity = (gnc_commodity *)parent->user_data2;
1018 iter->stamp = model->stamp;
1019 iter->user_data = ITER_IS_PRICE;
1021 iter->user_data3 = GINT_TO_POINTER(n);
1022 LEAVE(
"price iter %p (%s)", iter, iter_to_string(model, iter));
1023 return iter->user_data2 != NULL;
1032 gnc_tree_model_price_iter_parent (GtkTreeModel *tree_model,
1036 GncTreeModelPrice *model;
1037 gnc_commodity_table *ct;
1038 gnc_commodity * commodity;
1039 gnc_commodity_namespace *name_space;
1042 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (tree_model), FALSE);
1043 g_return_val_if_fail (iter != NULL, FALSE);
1044 g_return_val_if_fail (child != NULL, FALSE);
1046 model = GNC_TREE_MODEL_PRICE (tree_model);
1047 ENTER(
"model %p, iter %p, child %p (%s)",
1048 tree_model, iter, child, iter_to_string(model, child));
1050 if (child->user_data == ITER_IS_NAMESPACE)
1052 LEAVE(
"ns has no parent");
1056 if (child->user_data == ITER_IS_COMMODITY)
1062 iter->stamp = model->stamp;
1063 iter->user_data = ITER_IS_NAMESPACE;
1064 iter->user_data2 = name_space;
1065 iter->user_data3 = GINT_TO_POINTER(g_list_index(list, name_space));
1066 LEAVE(
"ns iter %p (%s)", iter, iter_to_string(model, iter));
1070 commodity = gnc_price_get_commodity ((GNCPrice*)child->user_data2);
1074 iter->stamp = model->stamp;
1075 iter->user_data = ITER_IS_COMMODITY;
1076 iter->user_data2 = commodity;
1077 iter->user_data3 = GINT_TO_POINTER(g_list_index(list, commodity));
1078 LEAVE(
"cm iter %p (%s)", iter, iter_to_string(model, iter));
1096 gnc_commodity *commodity;
1100 ENTER(
"model %p, price %p, iter %p", model, price, iter);
1101 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
1102 g_return_val_if_fail ((price != NULL), FALSE);
1103 g_return_val_if_fail ((iter != NULL), FALSE);
1105 commodity = gnc_price_get_commodity(price);
1106 if (commodity == NULL)
1108 LEAVE(
"no commodity");
1115 LEAVE(
"empty list");
1119 n = g_list_index(list, price);
1123 LEAVE(
"not in list");
1127 iter->stamp = model->stamp;
1128 iter->user_data = ITER_IS_PRICE;
1129 iter->user_data2 = price;
1130 iter->user_data3 = GINT_TO_POINTER(n);
1132 LEAVE(
"iter %s", iter_to_string(model, iter));
1145 GtkTreeIter tree_iter;
1146 GtkTreePath *tree_path;
1148 ENTER(
"model %p, price %p", model, price);
1149 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), NULL);
1150 g_return_val_if_fail (price != NULL, NULL);
1158 tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &tree_iter);
1161 gchar *path_string = gtk_tree_path_to_string(tree_path);
1162 LEAVE(
"path (2) %s", path_string);
1163 g_free(path_string);
1179 gnc_commodity *commodity,
1182 gnc_commodity_namespace *name_space;
1186 ENTER(
"model %p, commodity %p, iter %p", model, commodity, iter);
1187 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
1188 g_return_val_if_fail ((commodity != NULL), FALSE);
1189 g_return_val_if_fail ((iter != NULL), FALSE);
1192 if (name_space == NULL)
1194 LEAVE(
"no namespace");
1201 LEAVE(
"empty list");
1205 n = g_list_index(list, commodity);
1208 LEAVE(
"commodity not in list");
1212 iter->stamp = model->stamp;
1213 iter->user_data = ITER_IS_COMMODITY;
1214 iter->user_data2 = commodity;
1215 iter->user_data3 = GINT_TO_POINTER(n);
1216 LEAVE(
"iter %s", iter_to_string(model, iter));
1227 gnc_commodity_namespace *name_space,
1230 gnc_commodity_table *ct;
1234 ENTER(
"model %p, namespace %p, iter %p", model, name_space, iter);
1235 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
1236 g_return_val_if_fail ((name_space != NULL), FALSE);
1237 g_return_val_if_fail ((iter != NULL), FALSE);
1243 LEAVE(
"namespace list empty");
1247 n = g_list_index(list, name_space);
1250 LEAVE(
"namespace not found");
1254 iter->stamp = model->stamp;
1255 iter->user_data = ITER_IS_NAMESPACE;
1256 iter->user_data2 = name_space;
1257 iter->user_data3 = GINT_TO_POINTER(n);
1258 LEAVE(
"iter %s", iter_to_string(model, iter));
1266 typedef struct _remove_data
1268 GncTreeModelPrice *model;
1272 static GSList *pending_removals = NULL;
1286 gnc_tree_model_price_row_add (GncTreeModelPrice *model,
1290 GtkTreeModel *tree_model;
1291 GtkTreeIter tmp_iter;
1293 ENTER(
"model %p, iter (%p)%s", model, iter, iter_to_string(model, iter));
1303 while (model->stamp == 0);
1304 iter->stamp = model->stamp;
1307 tree_model = GTK_TREE_MODEL(model);
1308 path = gnc_tree_model_price_get_path (tree_model, iter);
1309 gtk_tree_model_row_inserted (tree_model, path, iter);
1316 if (gtk_tree_path_up(path) &&
1317 gtk_tree_path_get_depth(path) > 0 &&
1318 gtk_tree_model_get_iter(tree_model, &tmp_iter, path))
1321 gtk_tree_model_row_changed(tree_model, path, &tmp_iter);
1324 if (gtk_tree_model_iter_n_children(tree_model, &tmp_iter) == 1)
1325 gtk_tree_model_row_has_child_toggled(tree_model, path, &tmp_iter);
1328 while (gtk_tree_path_up(path) &&
1329 gtk_tree_path_get_depth(path) > 0 &&
1330 gtk_tree_model_get_iter(tree_model, &tmp_iter, path))
1332 gtk_tree_model_row_changed(tree_model, path, &tmp_iter);
1335 gtk_tree_path_free(path);
1341 if (gnc_tree_model_price_iter_has_child(tree_model, iter))
1343 path = gnc_tree_model_price_get_path(tree_model, iter);
1344 gtk_tree_model_row_has_child_toggled(tree_model, path, iter);
1345 gtk_tree_path_free(path);
1363 gnc_tree_model_price_row_delete (GncTreeModelPrice *model,
1366 GtkTreeModel *tree_model;
1369 g_return_if_fail(GNC_IS_TREE_MODEL_PRICE(model));
1370 g_return_if_fail(path);
1372 debug_path(
ENTER, path);
1374 tree_model = GTK_TREE_MODEL(model);
1384 while (model->stamp == 0);
1387 gtk_tree_model_row_deleted(tree_model, path);
1390 if (gtk_tree_path_up(path) &&
1391 gtk_tree_path_get_depth(path) > 0 &&
1392 gtk_tree_model_get_iter(tree_model, &iter, path))
1394 DEBUG(
"iter %s", iter_to_string(model, &iter));
1397 gtk_tree_model_row_changed(tree_model, path, &iter);
1400 if (!gtk_tree_model_iter_has_child(tree_model, &iter))
1401 gtk_tree_model_row_has_child_toggled(tree_model, path, &iter);
1404 while (gtk_tree_path_up(path) &&
1405 gtk_tree_path_get_depth(path) > 0 &&
1406 gtk_tree_model_get_iter(tree_model, &iter, path))
1408 DEBUG(
"iter %s", iter_to_string(model, &iter));
1409 gtk_tree_model_row_changed(tree_model, path, &iter);
1434 gnc_tree_model_price_do_deletions (gpointer price_db)
1439 while (pending_removals)
1442 pending_removals = g_slist_delete_link(pending_removals, pending_removals);
1446 debug_path(
DEBUG, data->path);
1449 gnc_tree_model_price_row_delete(data->model, data->path);
1450 gnc_pricedb_nth_price_reset_cache (price_db);
1452 gtk_tree_path_free(data->path);
1495 gnc_tree_model_price_event_handler (
QofInstance *entity,
1498 gpointer event_data)
1500 GncTreeModelPrice *model;
1506 ENTER(
"entity %p, event %d, model %p, event data %p",
1507 entity, event_type, user_data, event_data);
1508 model = (GncTreeModelPrice *)user_data;
1511 if (pending_removals)
1512 gnc_tree_model_price_do_deletions (model->price_db);
1515 g_return_if_fail(GNC_IS_TREE_MODEL_PRICE(model));
1518 if (GNC_IS_COMMODITY(entity))
1520 gnc_commodity *commodity;
1522 commodity = GNC_COMMODITY(entity);
1524 if (event_type != QOF_EVENT_DESTROY)
1533 else if (GNC_IS_COMMODITY_NAMESPACE(entity))
1535 gnc_commodity_namespace *name_space;
1537 name_space = GNC_COMMODITY_NAMESPACE(entity);
1539 if (event_type != QOF_EVENT_DESTROY)
1548 else if (GNC_IS_PRICE(entity))
1552 price = GNC_PRICE(entity);
1554 if (event_type != QOF_EVENT_DESTROY)
1573 DEBUG(
"add %s", name);
1574 gnc_pricedb_nth_price_reset_cache (model->price_db);
1575 gnc_tree_model_price_row_add (model, &iter);
1578 case QOF_EVENT_REMOVE:
1580 DEBUG(
"remove %s", name);
1581 path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter);
1584 LEAVE(
"not in model");
1589 data->model = model;
1591 pending_removals = g_slist_append (pending_removals, data);
1592 g_idle_add_full(G_PRIORITY_HIGH_IDLE,
1593 gnc_tree_model_price_do_deletions, model->price_db, NULL);
1598 case QOF_EVENT_MODIFY:
1599 DEBUG(
"change %s", name);
1600 path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter);
1603 LEAVE(
"not in model");
1606 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &iter, path))
1608 gtk_tree_path_free(path);
1609 LEAVE(
"can't find iter for path");
1612 gtk_tree_model_row_changed(GTK_TREE_MODEL(model), path, &iter);
1613 gtk_tree_path_free(path);
1618 LEAVE(
"ignored event for %s", name);
1621 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.