29 #include <glib/gi18n.h> 33 #include "gnc-component-manager.h" 35 #include "dialog-utils.h" 42 #include "gnc-ui-balances.h" 45 #define TREE_MODEL_ACCOUNT_CM_CLASS "tree-model-account" 48 static QofLogModule log_module = GNC_MOD_GUI;
53 static void gnc_tree_model_account_finalize (GObject *
object);
54 static void gnc_tree_model_account_dispose (GObject *
object);
57 static void gnc_tree_model_account_tree_model_init (GtkTreeModelIface *iface);
58 static GtkTreeModelFlags gnc_tree_model_account_get_flags (GtkTreeModel *tree_model);
59 static int gnc_tree_model_account_get_n_columns (GtkTreeModel *tree_model);
60 static GType gnc_tree_model_account_get_column_type (GtkTreeModel *tree_model,
62 static gboolean gnc_tree_model_account_get_iter (GtkTreeModel *tree_model,
65 static GtkTreePath *gnc_tree_model_account_get_path (GtkTreeModel *tree_model,
67 static void gnc_tree_model_account_get_value (GtkTreeModel *tree_model,
71 static gboolean gnc_tree_model_account_iter_next (GtkTreeModel *tree_model,
73 static gboolean gnc_tree_model_account_iter_children (GtkTreeModel *tree_model,
76 static gboolean gnc_tree_model_account_iter_has_child (GtkTreeModel *tree_model,
78 static int gnc_tree_model_account_iter_n_children (GtkTreeModel *tree_model,
80 static gboolean gnc_tree_model_account_iter_nth_child (GtkTreeModel *tree_model,
84 static gboolean gnc_tree_model_account_iter_parent (GtkTreeModel *tree_model,
89 static void gnc_tree_model_account_event_handler (QofInstance *entity,
99 gint event_handler_id;
100 gchar *negative_color;
102 GHashTable *account_values_hash;
107 gnc_tree_model_account, GNC_TYPE_TREE_MODEL,
109 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
110 gnc_tree_model_account_tree_model_init))
112 #define GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(o) \ 113 ((GncTreeModelAccountPrivate*)gnc_tree_model_account_get_instance_private((GncTreeModelAccount*)o)) 128 gnc_tree_model_account_update_color (gpointer gsettings, gchar *key, gpointer user_data)
134 g_return_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(user_data));
136 priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
139 g_hash_table_destroy (priv->account_values_hash);
140 priv->account_values_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
145 if (priv->negative_color)
146 g_free (priv->negative_color);
149 priv->negative_color = gnc_get_negative_color ();
151 priv->negative_color = NULL;
159 static GObjectClass *parent_class = NULL;
164 GObjectClass *o_class;
166 parent_class = g_type_class_peek_parent (klass);
168 o_class = G_OBJECT_CLASS(klass);
171 o_class->finalize = gnc_tree_model_account_finalize;
172 o_class->dispose = gnc_tree_model_account_dispose;
181 ENTER(
"model %p", model);
182 while (model->
stamp == 0)
184 model->
stamp = g_random_int ();
189 priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
193 if (priv->negative_color)
194 g_free (priv->negative_color);
197 priv->negative_color = gnc_get_negative_color ();
199 priv->negative_color = NULL;
202 priv->account_values_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
206 gnc_tree_model_account_update_color,
213 gnc_tree_model_account_finalize (GObject *
object)
218 g_return_if_fail (
object != NULL);
219 g_return_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(
object));
221 ENTER(
"model %p",
object);
223 model = GNC_TREE_MODEL_ACCOUNT(
object);
224 priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
228 if (G_OBJECT_CLASS(parent_class)->finalize)
229 G_OBJECT_CLASS(parent_class)->finalize (
object);
234 gnc_tree_model_account_dispose (GObject *
object)
239 g_return_if_fail (
object != NULL);
240 g_return_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(
object));
242 ENTER(
"model %p",
object);
244 model = GNC_TREE_MODEL_ACCOUNT(
object);
245 priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
247 if (priv->event_handler_id)
250 priv->event_handler_id = 0;
253 if (priv->negative_color)
254 g_free (priv->negative_color);
257 g_hash_table_destroy (priv->account_values_hash);
260 gnc_tree_model_account_update_color,
263 if (G_OBJECT_CLASS(parent_class)->dispose)
264 G_OBJECT_CLASS(parent_class)->dispose (
object);
280 ENTER(
"root %p", root);
282 for ( ; item; item = g_list_next (item))
285 priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
286 if (priv->root == root)
288 g_object_ref (G_OBJECT(model));
289 LEAVE(
"returning existing model %p", model);
290 return GTK_TREE_MODEL(model);
294 model = g_object_new (GNC_TYPE_TREE_MODEL_ACCOUNT, NULL);
296 priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
297 priv->book = gnc_get_current_book();
303 LEAVE(
"model %p", model);
304 return GTK_TREE_MODEL(model);
312 #define ITER_STRING_LEN 128 315 iter_to_string (GtkTreeIter *iter)
317 #ifdef G_THREADS_ENABLED 318 static GPrivate gtmits_buffer_key = G_PRIVATE_INIT(g_free);
321 string = g_private_get (>mits_buffer_key);
324 string = g_malloc(ITER_STRING_LEN + 1);
325 g_private_set (>mits_buffer_key,
string);
328 static char string[ITER_STRING_LEN + 1];
332 snprintf (
string, ITER_STRING_LEN,
333 "[stamp:%x data:%p (%s), %p, %d]",
334 iter->stamp, iter->user_data,
336 iter->user_data2, GPOINTER_TO_INT(iter->user_data3));
338 strcpy (
string,
"(null)");
348 gnc_tree_model_account_tree_model_init (GtkTreeModelIface *iface)
350 iface->get_flags = gnc_tree_model_account_get_flags;
351 iface->get_n_columns = gnc_tree_model_account_get_n_columns;
352 iface->get_column_type = gnc_tree_model_account_get_column_type;
353 iface->get_iter = gnc_tree_model_account_get_iter;
354 iface->get_path = gnc_tree_model_account_get_path;
355 iface->get_value = gnc_tree_model_account_get_value;
356 iface->iter_next = gnc_tree_model_account_iter_next;
357 iface->iter_children = gnc_tree_model_account_iter_children;
358 iface->iter_has_child = gnc_tree_model_account_iter_has_child;
359 iface->iter_n_children = gnc_tree_model_account_iter_n_children;
360 iface->iter_nth_child = gnc_tree_model_account_iter_nth_child;
361 iface->iter_parent = gnc_tree_model_account_iter_parent;
364 static GtkTreeModelFlags
365 gnc_tree_model_account_get_flags (GtkTreeModel *tree_model)
371 gnc_tree_model_account_get_n_columns (GtkTreeModel *tree_model)
373 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), -1);
375 return GNC_TREE_MODEL_ACCOUNT_NUM_COLUMNS;
379 gnc_tree_model_account_get_column_type (GtkTreeModel *tree_model,
int index)
381 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT (tree_model), G_TYPE_INVALID);
382 g_return_val_if_fail ((index < GNC_TREE_MODEL_ACCOUNT_NUM_COLUMNS) && (index >= 0), G_TYPE_INVALID);
386 case GNC_TREE_MODEL_ACCOUNT_COL_NAME:
387 case GNC_TREE_MODEL_ACCOUNT_COL_TYPE:
388 case GNC_TREE_MODEL_ACCOUNT_COL_COMMODITY:
389 case GNC_TREE_MODEL_ACCOUNT_COL_CODE:
390 case GNC_TREE_MODEL_ACCOUNT_COL_DESCRIPTION:
391 case GNC_TREE_MODEL_ACCOUNT_COL_PRESENT:
392 case GNC_TREE_MODEL_ACCOUNT_COL_PRESENT_REPORT:
393 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE:
394 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_REPORT:
395 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_PERIOD:
396 case GNC_TREE_MODEL_ACCOUNT_COL_CLEARED:
397 case GNC_TREE_MODEL_ACCOUNT_COL_CLEARED_REPORT:
398 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED:
399 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED_REPORT:
400 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED_DATE:
401 case GNC_TREE_MODEL_ACCOUNT_COL_FUTURE_MIN:
402 case GNC_TREE_MODEL_ACCOUNT_COL_FUTURE_MIN_REPORT:
403 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL:
404 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL_REPORT:
405 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL_PERIOD:
406 case GNC_TREE_MODEL_ACCOUNT_COL_NOTES:
407 case GNC_TREE_MODEL_ACCOUNT_COL_TAX_INFO:
408 case GNC_TREE_MODEL_ACCOUNT_COL_TAX_INFO_SUB_ACCT:
409 case GNC_TREE_MODEL_ACCOUNT_COL_LASTNUM:
411 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_PRESENT:
412 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_ACCOUNT:
413 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_BALANCE:
414 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_BALANCE_PERIOD:
415 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_CLEARED:
416 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_RECONCILED:
417 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_FUTURE_MIN:
418 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_TOTAL:
419 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_TOTAL_PERIOD:
420 return G_TYPE_STRING;
422 case GNC_TREE_MODEL_ACCOUNT_COL_HIDDEN:
423 case GNC_TREE_MODEL_ACCOUNT_COL_PLACEHOLDER:
424 case GNC_TREE_MODEL_ACCOUNT_COL_OPENING_BALANCE:
425 return G_TYPE_BOOLEAN;
428 g_assert_not_reached ();
429 return G_TYPE_INVALID;
434 gnc_tree_model_account_get_iter (GtkTreeModel *tree_model,
443 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), FALSE);
446 gchar *path_string = gtk_tree_path_to_string (path);
447 ENTER(
"model %p, iter %p, path %s", tree_model, iter, path_string);
448 g_free (path_string);
451 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
452 priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
454 if (gtk_tree_path_get_depth (path) <= 0)
460 indices = gtk_tree_path_get_indices (path);
463 LEAVE(
"bad root index");
468 account = priv->root;
469 for (i = 1; i < gtk_tree_path_get_depth (path); i++)
481 iter->stamp = model->
stamp;
482 iter->user_data = account;
483 iter->user_data2 = parent;
484 iter->user_data3 = GINT_TO_POINTER(indices[i - 1]);
486 LEAVE(
"iter %s", iter_to_string (iter));
491 gnc_tree_model_account_get_path (GtkTreeModel *tree_model,
500 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(model), NULL);
501 g_return_val_if_fail (iter != NULL, NULL);
502 g_return_val_if_fail (iter->user_data != NULL, NULL);
503 g_return_val_if_fail (iter->stamp == model->
stamp, NULL);
505 ENTER(
"model %p, iter %s", model, iter_to_string (iter));
507 priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
508 if (priv->root == NULL)
514 account = (
Account *) iter->user_data;
515 parent = (
Account *) iter->user_data2;
517 path = gtk_tree_path_new ();
523 gtk_tree_path_free (path);
527 gtk_tree_path_prepend_index (path, i);
533 gtk_tree_path_prepend_index (path, 0);
536 gchar *path_string = gtk_tree_path_to_string (path);
537 LEAVE(
"path (4) %s", path_string);
538 g_free (path_string);
550 priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
552 g_value_set_static_string (value, priv->negative_color);
554 g_value_set_static_string (value, NULL);
571 priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
572 if (acct == priv->root)
573 return g_strdup (
"");
575 t1 = gnc_accounting_period_fiscal_start ();
576 t2 = gnc_accounting_period_fiscal_end ();
579 return g_strdup (
"");
581 b3 = xaccAccountGetBalanceChangeForPeriod (acct, t1, t2, recurse);
582 if (gnc_reverse_balance (acct))
588 print_info = gnc_account_print_info (acct, TRUE);
594 row_changed_foreach_func (GtkTreeModel *model, GtkTreePath *path,
595 GtkTreeIter *iter, gpointer user_data)
597 gtk_tree_model_row_changed (model, path, iter);
609 g_hash_table_destroy (priv->account_values_hash);
610 priv->account_values_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
613 gtk_tree_model_foreach (GTK_TREE_MODEL(model), row_changed_foreach_func, NULL);
629 GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter);
631 gtk_tree_model_row_changed (GTK_TREE_MODEL(model), path, &iter);
632 gtk_tree_path_free (path);
638 for (gint col = 0; col <= GNC_TREE_MODEL_ACCOUNT_NUM_COLUMNS; col++)
640 gchar *key = g_strdup_printf (
"%s,%d", acct_guid_str, col);
642 g_hash_table_remove (hash, key);
654 if ((!priv->account_values_hash) || (!account))
657 clear_account_cached_values (model, priv->account_values_hash, account);
663 clear_account_cached_values (model, priv->account_values_hash, parent);
670 gint column, gchar **cached_string)
678 if ((!priv->account_values_hash) || (!account))
682 key = g_strdup_printf (
"%s,%d", acct_guid_str, column);
684 found = g_hash_table_lookup_extended (priv->account_values_hash, key,
688 *cached_string = g_strdup (value);
697 gint column, GValue *value)
701 if ((!priv->account_values_hash) || (!account))
705 if (G_VALUE_HOLDS_STRING(value))
708 const gchar *str = g_value_get_string (value);
712 key = g_strdup_printf (
"%s,%d", acct_guid_str, column);
714 g_hash_table_insert (priv->account_values_hash, key, g_strdup (str));
719 gnc_tree_model_account_get_value (GtkTreeModel *tree_model,
729 gchar *cached_string = NULL;
733 g_return_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(model));
734 g_return_if_fail (iter != NULL);
735 g_return_if_fail (iter->user_data != NULL);
736 g_return_if_fail (iter->stamp == model->
stamp);
738 ENTER(
"model %p, iter %s, col %d", tree_model,
739 iter_to_string (iter), column);
741 account = (
Account *) iter->user_data;
742 priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
745 if (gnc_tree_model_account_get_cached_value (model, account, column, &cached_string))
747 g_value_init (value, G_TYPE_STRING);
748 g_value_take_string (value, cached_string);
749 LEAVE(
"value in cache, '%s'", cached_string);
755 case GNC_TREE_MODEL_ACCOUNT_COL_NAME:
756 g_value_init (value, G_TYPE_STRING);
757 if (account == priv->root)
758 g_value_set_string (value, _(
"New top level account"));
762 case GNC_TREE_MODEL_ACCOUNT_COL_TYPE:
763 g_value_init (value, G_TYPE_STRING);
764 g_value_set_string (value,
767 case GNC_TREE_MODEL_ACCOUNT_COL_CODE:
768 g_value_init (value, G_TYPE_STRING);
771 case GNC_TREE_MODEL_ACCOUNT_COL_COMMODITY:
772 g_value_init (value, G_TYPE_STRING);
773 g_value_set_string (value,
776 case GNC_TREE_MODEL_ACCOUNT_COL_DESCRIPTION:
777 g_value_init (value, G_TYPE_STRING);
781 case GNC_TREE_MODEL_ACCOUNT_COL_PRESENT:
782 g_value_init (value, G_TYPE_STRING);
783 string = gnc_ui_account_get_print_balance (xaccAccountGetPresentBalanceInCurrency,
784 account, TRUE, &negative);
785 g_value_take_string (value,
string);
787 case GNC_TREE_MODEL_ACCOUNT_COL_PRESENT_REPORT:
788 g_value_init (value, G_TYPE_STRING);
789 string = gnc_ui_account_get_print_report_balance (xaccAccountGetPresentBalanceInCurrency,
790 account, TRUE, &negative);
791 g_value_take_string (value,
string);
793 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_PRESENT:
794 g_value_init (value, G_TYPE_STRING);
795 string = gnc_ui_account_get_print_balance (xaccAccountGetPresentBalanceInCurrency,
796 account, TRUE, &negative);
797 gnc_tree_model_account_set_color (model, negative, value);
801 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE:
802 g_value_init (value, G_TYPE_STRING);
803 string = gnc_ui_account_get_print_balance (xaccAccountGetBalanceInCurrency,
804 account, FALSE, &negative);
805 g_value_take_string (value,
string);
807 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_REPORT:
808 g_value_init (value, G_TYPE_STRING);
809 string = gnc_ui_account_get_print_report_balance (xaccAccountGetBalanceInCurrency,
810 account, FALSE, &negative);
811 g_value_take_string (value,
string);
813 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_BALANCE:
814 g_value_init (value, G_TYPE_STRING);
815 string = gnc_ui_account_get_print_balance (xaccAccountGetBalanceInCurrency,
816 account, FALSE, &negative);
817 gnc_tree_model_account_set_color (model, negative, value);
820 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_PERIOD:
821 g_value_init (value, G_TYPE_STRING);
822 string = gnc_tree_model_account_compute_period_balance (model, account, FALSE, &negative);
823 g_value_take_string (value,
string);
825 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_BALANCE_PERIOD:
826 g_value_init (value, G_TYPE_STRING);
827 string = gnc_tree_model_account_compute_period_balance (model, account, FALSE, &negative);
828 gnc_tree_model_account_set_color (model, negative, value);
832 case GNC_TREE_MODEL_ACCOUNT_COL_CLEARED:
833 g_value_init (value, G_TYPE_STRING);
834 string = gnc_ui_account_get_print_balance (xaccAccountGetClearedBalanceInCurrency,
835 account, TRUE, &negative);
836 g_value_take_string (value,
string);
838 case GNC_TREE_MODEL_ACCOUNT_COL_CLEARED_REPORT:
839 g_value_init (value, G_TYPE_STRING);
840 string = gnc_ui_account_get_print_report_balance (xaccAccountGetClearedBalanceInCurrency,
841 account, TRUE, &negative);
842 g_value_take_string (value,
string);
844 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_CLEARED:
845 g_value_init (value, G_TYPE_STRING);
846 string = gnc_ui_account_get_print_balance (xaccAccountGetClearedBalanceInCurrency,
847 account, TRUE, &negative);
848 gnc_tree_model_account_set_color (model, negative, value);
852 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED:
853 g_value_init (value, G_TYPE_STRING);
854 string = gnc_ui_account_get_print_balance (xaccAccountGetReconciledBalanceInCurrency,
855 account, TRUE, &negative);
856 g_value_take_string (value,
string);
858 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED_REPORT:
859 g_value_init (value, G_TYPE_STRING);
860 string = gnc_ui_account_get_print_report_balance (xaccAccountGetReconciledBalanceInCurrency,
861 account, TRUE, &negative);
862 g_value_take_string (value,
string);
864 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED_DATE:
865 g_value_init (value, G_TYPE_STRING);
870 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_RECONCILED:
871 g_value_init (value, G_TYPE_STRING);
872 string = gnc_ui_account_get_print_balance (xaccAccountGetReconciledBalanceInCurrency,
873 account, TRUE, &negative);
874 gnc_tree_model_account_set_color (model, negative, value);
878 case GNC_TREE_MODEL_ACCOUNT_COL_FUTURE_MIN:
879 g_value_init (value, G_TYPE_STRING);
880 string = gnc_ui_account_get_print_balance (xaccAccountGetProjectedMinimumBalanceInCurrency,
881 account, TRUE, &negative);
882 g_value_take_string (value,
string);
884 case GNC_TREE_MODEL_ACCOUNT_COL_FUTURE_MIN_REPORT:
885 g_value_init (value, G_TYPE_STRING);
886 string = gnc_ui_account_get_print_report_balance (xaccAccountGetProjectedMinimumBalanceInCurrency,
887 account, TRUE, &negative);
888 g_value_take_string (value,
string);
890 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_FUTURE_MIN:
891 g_value_init (value, G_TYPE_STRING);
892 string = gnc_ui_account_get_print_balance (xaccAccountGetProjectedMinimumBalanceInCurrency,
893 account, TRUE, &negative);
894 gnc_tree_model_account_set_color (model, negative, value);
898 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL:
899 g_value_init (value, G_TYPE_STRING);
900 string = gnc_ui_account_get_print_balance (xaccAccountGetBalanceInCurrency,
901 account, TRUE, &negative);
902 g_value_take_string (value,
string);
904 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL_REPORT:
905 g_value_init (value, G_TYPE_STRING);
906 string = gnc_ui_account_get_print_report_balance (xaccAccountGetBalanceInCurrency,
907 account, TRUE, &negative);
908 g_value_take_string (value,
string);
910 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_TOTAL:
911 g_value_init (value, G_TYPE_STRING);
912 string = gnc_ui_account_get_print_balance (xaccAccountGetBalanceInCurrency,
913 account, TRUE, &negative);
914 gnc_tree_model_account_set_color (model, negative, value);
917 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL_PERIOD:
918 g_value_init (value, G_TYPE_STRING);
919 string = gnc_tree_model_account_compute_period_balance (model, account, TRUE, &negative);
920 g_value_take_string (value,
string);
922 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_TOTAL_PERIOD:
923 g_value_init (value, G_TYPE_STRING);
924 string = gnc_tree_model_account_compute_period_balance (model, account, TRUE, &negative);
925 gnc_tree_model_account_set_color (model, negative, value);
929 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_ACCOUNT:
930 g_value_init (value, G_TYPE_STRING);
934 case GNC_TREE_MODEL_ACCOUNT_COL_NOTES:
935 g_value_init (value, G_TYPE_STRING);
939 case GNC_TREE_MODEL_ACCOUNT_COL_TAX_INFO:
940 g_value_init (value, G_TYPE_STRING);
941 g_value_take_string (value, gnc_ui_account_get_tax_info_string (account));
944 case GNC_TREE_MODEL_ACCOUNT_COL_TAX_INFO_SUB_ACCT:
945 g_value_init (value, G_TYPE_STRING);
946 g_value_take_string (value, gnc_ui_account_get_tax_info_sub_acct_string (account));
949 case GNC_TREE_MODEL_ACCOUNT_COL_LASTNUM:
950 g_value_init (value, G_TYPE_STRING);
954 case GNC_TREE_MODEL_ACCOUNT_COL_HIDDEN:
955 g_value_init (value, G_TYPE_BOOLEAN);
959 case GNC_TREE_MODEL_ACCOUNT_COL_PLACEHOLDER:
960 g_value_init (value, G_TYPE_BOOLEAN);
964 case GNC_TREE_MODEL_ACCOUNT_COL_OPENING_BALANCE:
965 g_value_init (value, G_TYPE_BOOLEAN);
970 g_assert_not_reached ();
975 gnc_tree_model_account_set_cached_value (model, account, column, value);
981 gnc_tree_model_account_iter_next (GtkTreeModel *tree_model,
988 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(model), FALSE);
989 g_return_val_if_fail (iter != NULL, FALSE);
990 g_return_val_if_fail (iter->user_data != NULL, FALSE);
991 g_return_val_if_fail (iter->stamp == model->
stamp, FALSE);
993 ENTER(
"model %p, iter %s", tree_model, iter_to_string (iter));
995 parent = (
Account *) iter->user_data2;
1004 i = GPOINTER_TO_INT(iter->user_data3);
1006 if (account == NULL)
1009 LEAVE(
"failed (3)");
1013 iter->user_data = account;
1014 iter->user_data2 = parent;
1015 iter->user_data3 = GINT_TO_POINTER(i + 1);
1017 LEAVE(
"iter %s", iter_to_string (iter));
1022 gnc_tree_model_account_iter_children (GtkTreeModel *tree_model,
1024 GtkTreeIter *parent_iter)
1030 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), FALSE);
1031 ENTER(
"model %p, iter %p (to be filed in), parent %s",
1032 tree_model, iter, (parent_iter ? iter_to_string (parent_iter) :
"(null)"));
1034 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1035 priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
1037 if (priv->root == NULL)
1040 LEAVE(
"failed (no root)");
1047 iter->user_data = priv->root;
1048 iter->user_data2 = NULL;
1049 iter->user_data3 = GINT_TO_POINTER(0);
1050 iter->stamp = model->
stamp;
1051 LEAVE(
"iter (2) %s", iter_to_string (iter));
1059 parent = (
Account *)parent_iter->user_data;
1062 if (account == NULL)
1065 LEAVE(
"failed (child account is null)");
1069 iter->user_data = account;
1070 iter->user_data2 = parent;
1071 iter->user_data3 = GINT_TO_POINTER(0);
1072 iter->stamp = model->
stamp;
1073 LEAVE(
"iter (3) %s", iter_to_string (iter));
1078 gnc_tree_model_account_iter_has_child (GtkTreeModel *tree_model,
1084 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), FALSE);
1086 ENTER(
"model %p, iter %s", tree_model, iter_to_string (iter));
1088 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1094 account = (
Account *) iter->user_data;
1106 gnc_tree_model_account_iter_n_children (GtkTreeModel *tree_model,
1112 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), FALSE);
1113 ENTER(
"model %p, iter %s", tree_model, iter_to_string (iter));
1115 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1121 LEAVE(
"count is 1");
1130 LEAVE(
"count is %d", num);
1135 gnc_tree_model_account_iter_nth_child (GtkTreeModel *tree_model,
1137 GtkTreeIter *parent_iter,
1146 gchar *parent_string;
1147 parent_string = g_strdup (iter_to_string (parent_iter));
1148 ENTER(
"model %p, iter %s, parent_iter %s, n %d",
1149 tree_model, iter_to_string (iter),
1151 g_free (parent_string);
1155 ENTER(
"model %p, iter %s, parent_iter (null), n %d",
1156 tree_model, iter_to_string (iter), n);
1160 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1161 priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
1168 LEAVE(
"bad root index");
1172 iter->user_data = priv->root;
1173 iter->user_data2 = NULL;
1174 iter->user_data3 = GINT_TO_POINTER(0);
1175 iter->stamp = model->
stamp;
1176 LEAVE(
"root %s", iter_to_string (iter));
1183 parent = (
Account *)parent_iter->user_data;
1185 if (account == NULL)
1188 LEAVE(
"failed (2)");
1192 iter->user_data = account;
1193 iter->user_data2 = parent;
1194 iter->user_data3 = GINT_TO_POINTER(n);
1195 iter->stamp = model->
stamp;
1196 LEAVE(
"iter (2) %s", iter_to_string (iter));
1201 gnc_tree_model_account_iter_parent (GtkTreeModel *tree_model,
1211 gchar *child_string;
1213 child_string = g_strdup (iter_to_string (child));
1214 ENTER(
"model %p, iter %s, child %s",
1215 tree_model, iter_to_string (iter),
1217 g_free (child_string);
1221 ENTER(
"model %p, iter %s, child (null)",
1222 tree_model, iter_to_string (iter));
1226 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1232 account = (
Account *) child->user_data;
1234 if (account == NULL)
1238 LEAVE(
"failed (1)");
1252 iter->user_data = account;
1253 iter->user_data2 = parent;
1254 iter->user_data3 = GINT_TO_POINTER(i);
1255 iter->stamp = model->
stamp;
1256 LEAVE(
"iter (2) %s", iter_to_string (iter));
1273 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(model), NULL);
1274 g_return_val_if_fail (iter != NULL, NULL);
1275 g_return_val_if_fail (iter->user_data != NULL, NULL);
1276 g_return_val_if_fail (iter->stamp == model->
stamp, NULL);
1278 return (
Account *) iter->user_data;
1295 ENTER(
"model %p, account %p, iter %p", model, account, iter);
1300 iter->user_data = account;
1301 iter->stamp = model->
stamp;
1303 priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
1304 if (account == priv->root)
1306 iter->user_data2 = NULL;
1307 iter->user_data3 = GINT_TO_POINTER(0);
1308 LEAVE(
"Matched root");
1314 LEAVE(
"Root doesn't match");
1320 iter->user_data2 = parent;
1321 iter->user_data3 = GINT_TO_POINTER(i);
1322 LEAVE(
"iter %s", iter_to_string (iter));
1335 GtkTreeIter tree_iter;
1336 GtkTreePath *tree_path;
1338 ENTER(
"model %p, account %p", model, account);
1349 tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &tree_iter);
1352 gchar *path_string = gtk_tree_path_to_string (tree_path);
1353 LEAVE(
"path (2) %s", path_string);
1354 g_free (path_string);
1371 while (!model->
stamp);
1375 propagate_change (GtkTreeModel *model, GtkTreePath *path, gint toggle_if_num)
1380 if (!gtk_tree_path_up (path))
1384 if (gtk_tree_path_get_depth (path) == 0)
1388 if (gtk_tree_model_get_iter (model, &iter, path))
1390 gtk_tree_model_row_changed (model, path, &iter);
1391 if (gtk_tree_model_iter_n_children (model, &iter) == toggle_if_num)
1392 gtk_tree_model_row_has_child_toggled (model, path, &iter);
1396 while (gtk_tree_path_up (path) && gtk_tree_path_get_depth (path) > 0 &&
1397 gtk_tree_model_get_iter (model, &iter, path))
1399 gtk_tree_model_row_changed (model, path, &iter);
1432 gnc_tree_model_account_event_handler (QofInstance *entity,
1438 const gchar *parent_name;
1439 GtkTreePath *path = NULL;
1443 g_return_if_fail (model);
1445 if (!GNC_IS_ACCOUNT(entity))
1448 ENTER(
"entity %p of type %d, model %p, event_data %p",
1449 entity, event_type, model, ed);
1450 priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
1452 account = GNC_ACCOUNT(entity);
1454 if (gnc_account_get_book (account) != priv->book)
1456 LEAVE(
"not in this book");
1461 LEAVE(
"not in this model");
1466 if (event_type != QOF_EVENT_ADD)
1467 gnc_tree_model_account_clear_cached_values (model, account);
1478 DEBUG(
"can't generate path");
1481 increment_stamp (model);
1482 if (!gnc_tree_model_account_get_iter (GTK_TREE_MODEL(model), &iter, path))
1484 DEBUG(
"can't generate iter");
1487 gtk_tree_model_row_inserted (GTK_TREE_MODEL(model), path, &iter);
1488 propagate_change (GTK_TREE_MODEL(model), path, 1);
1491 case QOF_EVENT_REMOVE:
1494 parent = ed->node ? GNC_ACCOUNT(ed->node) : priv->root;
1496 DEBUG(
"remove child %d of account %p (%s)", ed->idx, parent, parent_name);
1500 DEBUG(
"can't generate path");
1503 increment_stamp (model);
1504 gtk_tree_path_append_index (path, ed->idx);
1505 gtk_tree_model_row_deleted (GTK_TREE_MODEL(model), path);
1506 propagate_change (GTK_TREE_MODEL(model), path, 0);
1509 case QOF_EVENT_MODIFY:
1514 DEBUG(
"can't generate path");
1517 if (!gnc_tree_model_account_get_iter (GTK_TREE_MODEL(model), &iter, path))
1519 DEBUG(
"can't generate iter");
1522 gtk_tree_model_row_changed (GTK_TREE_MODEL(model), path, &iter);
1523 propagate_change (GTK_TREE_MODEL(model), path, -1);
1527 LEAVE(
"unknown event type");
1532 gtk_tree_path_free (path);
Account * gnc_account_get_parent(const Account *acc)
This routine returns a pointer to the parent of the specified account.
const char * xaccAccountGetLastNum(const Account *acc)
Get the last num field of an Account.
const char * gnc_print_amount_with_bidi_ltr_isolate(gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
const GList * gnc_gobject_tracking_get_list(const gchar *name)
Get a list of all known objects of a specified type.
gulong gnc_prefs_register_cb(const char *group, const gchar *pref_name, gpointer func, gpointer user_data)
Register a callback that gets triggered when the given preference changes.
void(* QofEventHandler)(QofInstance *ent, QofEventId event_type, gpointer handler_data, gpointer event_data)
Handler invoked when an event is generated.
utility functions for the GnuCash UI
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account's account type.
const char * xaccAccountGetCode(const Account *acc)
Get the account's accounting code.
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value...
#define DEBUG(format, args...)
Print a debugging message.
The class data structure for an account tree model.
Account * gnc_tree_model_account_get_account(GncTreeModelAccount *model, GtkTreeIter *iter)
Convert a model/iter pair to a gnucash account.
gchar * guid_to_string_buff(const GncGUID *guid, gchar *str)
The guid_to_string_buff() routine puts a null-terminated string encoding of the id into the memory po...
#define ENTER(format, args...)
Print a function entry debugging message.
#define gnc_leave_return_val_if_fail(test, val)
Replacement for g_return_val_if_fail, but calls LEAVE if the test fails.
gboolean gnc_tree_model_account_get_iter_from_account(GncTreeModelAccount *model, Account *account, GtkTreeIter *iter)
Convert a model/account pair into a gtk_tree_model_iter.
gboolean gnc_numeric_negative_p(gnc_numeric a)
Returns 1 if a < 0, otherwise returns 0.
gint qof_event_register_handler(QofEventHandler handler, gpointer user_data)
Register a handler for events.
const char * xaccAccountGetColor(const Account *acc)
Get the account's color.
GtkTreeModel implementation for gnucash account tree.
#define xaccAccountGetGUID(X)
char * qof_print_date(time64 secs)
Convenience; calls through to qof_print_date_dmy_buff().
void gnc_tree_model_account_clear_cache(GncTreeModelAccount *model)
Clear the tree model account cached values.
Account handling public routines.
gint QofEventId
Define the type of events allowed.
GtkTreeModel * gnc_tree_model_account_new(Account *root)
Create a new GtkTreeModel for manipulating gnucash accounts.
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
const char * xaccAccountGetDescription(const Account *acc)
Get the account's description.
General utilities for dealing with accounting periods.
void qof_event_unregister_handler(gint handler_id)
Unregister an event handler.
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
Retrieve the full name for the specified commodity.
The instance private data for an account tree model.
Additional event handling code.
gint gnc_account_n_children(const Account *account)
Return the number of children of the specified account.
All type declarations for the whole Gnucash engine.
gboolean xaccAccountGetReconcileLastDate(const Account *acc, time64 *last_date)
DOCUMENT ME!
gboolean xaccAccountGetHidden(const Account *acc)
Get the "hidden" flag for an account.
Generic api to store and retrieve preferences.
gboolean xaccAccountGetIsOpeningBalance(const Account *acc)
Get the "opening-balance" flag for an account.
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity.
GtkTreePath * gnc_tree_model_account_get_path_from_account(GncTreeModelAccount *model, Account *account)
Convert a model/account pair into a gtk_tree_model_path.
gboolean xaccAccountGetPlaceholder(const Account *acc)
Get the "placeholder" flag for an account.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
#define LEAVE(format, args...)
Print a function exit debugging message.
Account * gnc_account_nth_child(const Account *parent, gint num)
Return the n'th child account of the specified parent account.
gint gnc_account_child_index(const Account *parent, const Account *child)
Return the index of the specified child within the list of the parent's children. ...
gint64 time64
Many systems, including Microsoft Windows and BSD-derived Unixes like Darwin, are retaining the int-3...
The instance data structure for an account tree model.
Account * gnc_account_get_root(Account *acc)
This routine returns the root account of the account tree that the specified account belongs to...
const char * xaccAccountGetName(const Account *acc)
Get the account's name.
const char * xaccAccountGetTypeStr(GNCAccountType type)
The xaccAccountGetTypeStr() routine returns a string suitable for use in the GUI/Interface.
int stamp
The state of the model.
Commodity handling public routines.
void gnc_prefs_remove_cb_by_func(const gchar *group, const gchar *pref_name, gpointer func, gpointer user_data)
Remove a function that was registered for a callback when the given preference changed.
const char * xaccAccountGetNotes(const Account *acc)
Get the account's notes.