29 #include <glib/gi18n.h> 33 #include "gnc-component-manager.h" 35 #include "dialog-utils.h" 42 #include "gnc-ui-balances.h" 44 #include <gnc-locale-tax.h> 46 #define TREE_MODEL_ACCOUNT_CM_CLASS "tree-model-account" 49 static QofLogModule log_module = GNC_MOD_GUI;
52 static void gnc_tree_model_account_finalize (GObject *
object);
53 static void gnc_tree_model_account_dispose (GObject *
object);
56 static void gnc_tree_model_account_tree_model_init (GtkTreeModelIface *iface);
57 static GtkTreeModelFlags gnc_tree_model_account_get_flags (GtkTreeModel *tree_model);
58 static int gnc_tree_model_account_get_n_columns (GtkTreeModel *tree_model);
59 static GType gnc_tree_model_account_get_column_type (GtkTreeModel *tree_model,
61 static gboolean gnc_tree_model_account_get_iter (GtkTreeModel *tree_model,
64 static GtkTreePath *gnc_tree_model_account_get_path (GtkTreeModel *tree_model,
66 static void gnc_tree_model_account_get_value (GtkTreeModel *tree_model,
70 static gboolean gnc_tree_model_account_iter_next (GtkTreeModel *tree_model,
72 static gboolean gnc_tree_model_account_iter_children (GtkTreeModel *tree_model,
75 static gboolean gnc_tree_model_account_iter_has_child (GtkTreeModel *tree_model,
77 static int gnc_tree_model_account_iter_n_children (GtkTreeModel *tree_model,
79 static gboolean gnc_tree_model_account_iter_nth_child (GtkTreeModel *tree_model,
83 static gboolean gnc_tree_model_account_iter_parent (GtkTreeModel *tree_model,
88 static void gnc_tree_model_account_event_handler (
QofInstance *entity,
90 GncTreeModelAccount *model,
101 gint event_handler_id;
102 gchar *negative_color;
104 GHashTable *account_values_hash;
109 gnc_tree_model_account, GNC_TYPE_TREE_MODEL,
110 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
111 gnc_tree_model_account_tree_model_init))
125 gnc_tree_model_account_update_color (gpointer gsettings, gchar *key, gpointer user_data)
129 g_return_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(user_data));
130 GncTreeModelAccount *model = user_data;
133 g_hash_table_destroy (model->account_values_hash);
134 model->account_values_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
139 if (model->negative_color)
140 g_free (model->negative_color);
143 model->negative_color = gnc_get_negative_color ();
145 model->negative_color = NULL;
153 gnc_tree_model_account_class_init (GncTreeModelAccountClass *klass)
155 GObjectClass *o_class;
157 o_class = G_OBJECT_CLASS(klass);
160 o_class->finalize = gnc_tree_model_account_finalize;
161 o_class->dispose = gnc_tree_model_account_dispose;
165 gnc_tree_model_account_init (GncTreeModelAccount *model)
169 ENTER(
"model %p", model);
170 while (model->stamp == 0)
172 model->stamp = g_random_int ();
180 if (model->negative_color)
181 g_free (model->negative_color);
184 model->negative_color = gnc_get_negative_color ();
186 model->negative_color = NULL;
189 model->account_values_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
193 gnc_tree_model_account_update_color,
200 gnc_tree_model_account_finalize (GObject *
object)
202 GncTreeModelAccount *model;
204 g_return_if_fail (
object != NULL);
205 g_return_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(
object));
207 ENTER(
"model %p",
object);
209 model = GNC_TREE_MODEL_ACCOUNT(
object);
213 G_OBJECT_CLASS(gnc_tree_model_account_parent_class)->finalize (
object);
218 gnc_tree_model_account_dispose (GObject *
object)
220 GncTreeModelAccount *model;
222 g_return_if_fail (
object != NULL);
223 g_return_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(
object));
225 ENTER(
"model %p",
object);
227 model = GNC_TREE_MODEL_ACCOUNT(
object);
229 if (model->event_handler_id)
232 model->event_handler_id = 0;
235 if (model->negative_color)
236 g_free (model->negative_color);
239 g_hash_table_destroy (model->account_values_hash);
242 gnc_tree_model_account_update_color,
246 G_OBJECT_CLASS(gnc_tree_model_account_parent_class)->dispose (
object);
258 GncTreeModelAccount *model;
261 ENTER(
"root %p", root);
263 for ( ; item; item = g_list_next (item))
265 model = (GncTreeModelAccount *)item->data;
266 if (model->root == root)
268 g_object_ref (G_OBJECT(model));
269 LEAVE(
"returning existing model %p", model);
270 return GTK_TREE_MODEL(model);
274 model = g_object_new (GNC_TYPE_TREE_MODEL_ACCOUNT, NULL);
276 model->book = gnc_get_current_book();
282 LEAVE(
"model %p", model);
283 return GTK_TREE_MODEL(model);
291 #define ITER_STRING_LEN 128 294 iter_to_string (GtkTreeIter *iter)
296 #ifdef G_THREADS_ENABLED 297 static GPrivate gtmits_buffer_key = G_PRIVATE_INIT(g_free);
300 string = g_private_get (>mits_buffer_key);
303 string = g_malloc(ITER_STRING_LEN + 1);
304 g_private_set (>mits_buffer_key,
string);
307 static char string[ITER_STRING_LEN + 1];
311 snprintf (
string, ITER_STRING_LEN,
312 "[stamp:%x data:%p (%s), %p, %d]",
313 iter->stamp, iter->user_data,
315 iter->user_data2, GPOINTER_TO_INT(iter->user_data3));
317 strcpy (
string,
"(null)");
327 gnc_tree_model_account_tree_model_init (GtkTreeModelIface *iface)
329 iface->get_flags = gnc_tree_model_account_get_flags;
330 iface->get_n_columns = gnc_tree_model_account_get_n_columns;
331 iface->get_column_type = gnc_tree_model_account_get_column_type;
332 iface->get_iter = gnc_tree_model_account_get_iter;
333 iface->get_path = gnc_tree_model_account_get_path;
334 iface->get_value = gnc_tree_model_account_get_value;
335 iface->iter_next = gnc_tree_model_account_iter_next;
336 iface->iter_children = gnc_tree_model_account_iter_children;
337 iface->iter_has_child = gnc_tree_model_account_iter_has_child;
338 iface->iter_n_children = gnc_tree_model_account_iter_n_children;
339 iface->iter_nth_child = gnc_tree_model_account_iter_nth_child;
340 iface->iter_parent = gnc_tree_model_account_iter_parent;
343 static GtkTreeModelFlags
344 gnc_tree_model_account_get_flags (GtkTreeModel *tree_model)
350 gnc_tree_model_account_get_n_columns (GtkTreeModel *tree_model)
352 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), -1);
354 return GNC_TREE_MODEL_ACCOUNT_NUM_COLUMNS;
358 gnc_tree_model_account_get_column_type (GtkTreeModel *tree_model,
int index)
360 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT (tree_model), G_TYPE_INVALID);
361 g_return_val_if_fail ((index < GNC_TREE_MODEL_ACCOUNT_NUM_COLUMNS) && (index >= 0), G_TYPE_INVALID);
365 case GNC_TREE_MODEL_ACCOUNT_COL_NAME:
366 case GNC_TREE_MODEL_ACCOUNT_COL_TYPE:
367 case GNC_TREE_MODEL_ACCOUNT_COL_COMMODITY:
368 case GNC_TREE_MODEL_ACCOUNT_COL_CODE:
369 case GNC_TREE_MODEL_ACCOUNT_COL_DESCRIPTION:
370 case GNC_TREE_MODEL_ACCOUNT_COL_PRESENT:
371 case GNC_TREE_MODEL_ACCOUNT_COL_PRESENT_REPORT:
372 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE:
373 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_REPORT:
374 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_PERIOD:
375 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_LIMIT:
376 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_LIMIT_EXPLANATION:
377 case GNC_TREE_MODEL_ACCOUNT_COL_CLEARED:
378 case GNC_TREE_MODEL_ACCOUNT_COL_CLEARED_REPORT:
379 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED:
380 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED_REPORT:
381 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED_DATE:
382 case GNC_TREE_MODEL_ACCOUNT_COL_EARLIEST_DATE:
383 case GNC_TREE_MODEL_ACCOUNT_COL_FUTURE_MIN:
384 case GNC_TREE_MODEL_ACCOUNT_COL_FUTURE_MIN_REPORT:
385 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL:
386 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL_REPORT:
387 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL_PERIOD:
388 case GNC_TREE_MODEL_ACCOUNT_COL_NOTES:
389 case GNC_TREE_MODEL_ACCOUNT_COL_TAX_INFO:
390 case GNC_TREE_MODEL_ACCOUNT_COL_TAX_INFO_SUB_ACCT:
391 case GNC_TREE_MODEL_ACCOUNT_COL_LASTNUM:
393 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_PRESENT:
394 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_ACCOUNT:
395 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_BALANCE:
396 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_BALANCE_PERIOD:
397 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_CLEARED:
398 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_RECONCILED:
399 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_FUTURE_MIN:
400 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_TOTAL:
401 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_TOTAL_PERIOD:
402 return G_TYPE_STRING;
404 case GNC_TREE_MODEL_ACCOUNT_COL_HIDDEN:
405 case GNC_TREE_MODEL_ACCOUNT_COL_PLACEHOLDER:
406 case GNC_TREE_MODEL_ACCOUNT_COL_OPENING_BALANCE:
407 return G_TYPE_BOOLEAN;
410 g_assert_not_reached ();
411 return G_TYPE_INVALID;
416 gnc_tree_model_account_get_iter (GtkTreeModel *tree_model,
420 GncTreeModelAccount *model;
424 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), FALSE);
427 gchar *path_string = gtk_tree_path_to_string (path);
428 ENTER(
"model %p, iter %p, path %s", tree_model, iter, path_string);
429 g_free (path_string);
432 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
434 if (gtk_tree_path_get_depth (path) <= 0)
440 indices = gtk_tree_path_get_indices (path);
443 LEAVE(
"bad root index");
448 account = model->root;
449 for (i = 1; i < gtk_tree_path_get_depth (path); i++)
461 iter->stamp = model->stamp;
462 iter->user_data = account;
463 iter->user_data2 = parent;
464 iter->user_data3 = GINT_TO_POINTER(indices[i - 1]);
466 LEAVE(
"iter %s", iter_to_string (iter));
471 gnc_tree_model_account_get_path (GtkTreeModel *tree_model,
474 GncTreeModelAccount *model = GNC_TREE_MODEL_ACCOUNT(tree_model);
479 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(model), NULL);
480 g_return_val_if_fail (iter != NULL, NULL);
481 g_return_val_if_fail (iter->user_data != NULL, NULL);
482 g_return_val_if_fail (iter->stamp == model->stamp, NULL);
484 ENTER(
"model %p, iter %s", model, iter_to_string (iter));
486 if (model->root == NULL)
492 account = (
Account *) iter->user_data;
493 parent = (
Account *) iter->user_data2;
495 path = gtk_tree_path_new ();
501 gtk_tree_path_free (path);
505 gtk_tree_path_prepend_index (path, i);
511 gtk_tree_path_prepend_index (path, 0);
514 gchar *path_string = gtk_tree_path_to_string (path);
515 LEAVE(
"path (4) %s", path_string);
516 g_free (path_string);
522 gnc_tree_model_account_set_color (GncTreeModelAccount *model,
527 g_value_set_static_string (value, model->negative_color);
529 g_value_set_static_string (value, NULL);
533 gnc_tree_model_account_compute_period_balance (GncTreeModelAccount *model,
545 if (acct == model->root)
546 return g_strdup (
"");
548 t1 = gnc_accounting_period_fiscal_start ();
549 t2 = gnc_accounting_period_fiscal_end ();
552 return g_strdup (
"");
554 b3 = xaccAccountGetBalanceChangeForPeriod (acct, t1, t2, recurse);
555 if (gnc_reverse_balance (acct))
561 print_info = gnc_account_print_info (acct, TRUE);
567 row_changed_foreach_func (GtkTreeModel *model, GtkTreePath *path,
568 GtkTreeIter *iter, gpointer user_data)
570 gtk_tree_model_row_changed (model, path, iter);
580 g_hash_table_destroy (model->account_values_hash);
581 model->account_values_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
584 gtk_tree_model_foreach (GTK_TREE_MODEL(model), row_changed_foreach_func, NULL);
589 clear_account_cached_values (GncTreeModelAccount *model, GHashTable *hash,
Account *account)
600 GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter);
602 gtk_tree_model_row_changed (GTK_TREE_MODEL(model), path, &iter);
603 gtk_tree_path_free (path);
609 for (gint col = 0; col <= GNC_TREE_MODEL_ACCOUNT_NUM_COLUMNS; col++)
611 gchar *key = g_strdup_printf (
"%s,%d", acct_guid_str, col);
613 g_hash_table_remove (hash, key);
619 gnc_tree_model_account_clear_cached_values (GncTreeModelAccount *model,
Account *account)
624 if ((!model->account_values_hash) || (!account))
627 clear_account_cached_values (model, model->account_values_hash, account);
633 clear_account_cached_values (model, model->account_values_hash, parent);
639 gnc_tree_model_account_get_cached_value (GncTreeModelAccount *model,
Account *account,
640 gint column, gchar **cached_string)
647 if ((!model->account_values_hash) || (!account))
651 key = g_strdup_printf (
"%s,%d", acct_guid_str, column);
653 found = g_hash_table_lookup_extended (model->account_values_hash, key,
657 *cached_string = g_strdup (value);
665 gnc_tree_model_account_set_cached_value (GncTreeModelAccount *model,
Account *account,
666 gint column, GValue *value)
668 if ((!model->account_values_hash) || (!account))
672 if (G_VALUE_HOLDS_STRING(value))
675 const gchar *str = g_value_get_string (value);
679 key = g_strdup_printf (
"%s,%d", acct_guid_str, column);
681 g_hash_table_insert (model->account_values_hash, key, g_strdup (str));
686 gnc_tree_model_account_get_value (GtkTreeModel *tree_model,
691 GncTreeModelAccount *model = GNC_TREE_MODEL_ACCOUNT(tree_model);
695 gchar *cached_string = NULL;
699 g_return_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(model));
700 g_return_if_fail (iter != NULL);
701 g_return_if_fail (iter->user_data != NULL);
702 g_return_if_fail (iter->stamp == model->stamp);
704 ENTER(
"model %p, iter %s, col %d", tree_model,
705 iter_to_string (iter), column);
707 account = (
Account *) iter->user_data;
710 if (gnc_tree_model_account_get_cached_value (model, account, column, &cached_string))
712 g_value_init (value, G_TYPE_STRING);
713 g_value_take_string (value, cached_string);
714 LEAVE(
"value in cache, '%s'", cached_string);
720 case GNC_TREE_MODEL_ACCOUNT_COL_NAME:
721 g_value_init (value, G_TYPE_STRING);
722 if (account == model->root)
723 g_value_set_string (value, _(
"New top level account"));
727 case GNC_TREE_MODEL_ACCOUNT_COL_TYPE:
728 g_value_init (value, G_TYPE_STRING);
729 g_value_set_string (value,
732 case GNC_TREE_MODEL_ACCOUNT_COL_CODE:
733 g_value_init (value, G_TYPE_STRING);
736 case GNC_TREE_MODEL_ACCOUNT_COL_COMMODITY:
737 g_value_init (value, G_TYPE_STRING);
738 g_value_set_string (value,
741 case GNC_TREE_MODEL_ACCOUNT_COL_DESCRIPTION:
742 g_value_init (value, G_TYPE_STRING);
746 case GNC_TREE_MODEL_ACCOUNT_COL_PRESENT:
747 g_value_init (value, G_TYPE_STRING);
748 string = gnc_ui_account_get_print_balance (xaccAccountGetPresentBalanceInCurrency,
749 account, TRUE, &negative);
750 g_value_take_string (value,
string);
752 case GNC_TREE_MODEL_ACCOUNT_COL_PRESENT_REPORT:
753 g_value_init (value, G_TYPE_STRING);
754 string = gnc_ui_account_get_print_report_balance (xaccAccountGetPresentBalanceInCurrency,
755 account, TRUE, &negative);
756 g_value_take_string (value,
string);
758 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_PRESENT:
759 g_value_init (value, G_TYPE_STRING);
760 string = gnc_ui_account_get_print_balance (xaccAccountGetPresentBalanceInCurrency,
761 account, TRUE, &negative);
762 gnc_tree_model_account_set_color (model, negative, value);
766 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE:
767 g_value_init (value, G_TYPE_STRING);
768 string = gnc_ui_account_get_print_balance (xaccAccountGetBalanceInCurrency,
769 account, FALSE, &negative);
770 g_value_take_string (value,
string);
772 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_REPORT:
773 g_value_init (value, G_TYPE_STRING);
774 string = gnc_ui_account_get_print_report_balance (xaccAccountGetBalanceInCurrency,
775 account, FALSE, &negative);
776 g_value_take_string (value,
string);
778 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_BALANCE:
779 g_value_init (value, G_TYPE_STRING);
780 string = gnc_ui_account_get_print_balance (xaccAccountGetBalanceInCurrency,
781 account, FALSE, &negative);
782 gnc_tree_model_account_set_color (model, negative, value);
785 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_PERIOD:
786 g_value_init (value, G_TYPE_STRING);
787 string = gnc_tree_model_account_compute_period_balance (model, account, FALSE, &negative);
788 g_value_take_string (value,
string);
790 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_BALANCE_PERIOD:
791 g_value_init (value, G_TYPE_STRING);
792 string = gnc_tree_model_account_compute_period_balance (model, account, FALSE, &negative);
793 gnc_tree_model_account_set_color (model, negative, value);
797 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_LIMIT:
798 g_value_init (value, G_TYPE_STRING);
799 string = gnc_ui_account_get_balance_limit_icon_name (account);
800 g_value_take_string (value,
string);
803 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_LIMIT_EXPLANATION:
804 g_value_init (value, G_TYPE_STRING);
805 string = gnc_ui_account_get_balance_limit_explanation (account);
806 g_value_take_string (value,
string);
809 case GNC_TREE_MODEL_ACCOUNT_COL_CLEARED:
810 g_value_init (value, G_TYPE_STRING);
811 string = gnc_ui_account_get_print_balance (xaccAccountGetClearedBalanceInCurrency,
812 account, TRUE, &negative);
813 g_value_take_string (value,
string);
815 case GNC_TREE_MODEL_ACCOUNT_COL_CLEARED_REPORT:
816 g_value_init (value, G_TYPE_STRING);
817 string = gnc_ui_account_get_print_report_balance (xaccAccountGetClearedBalanceInCurrency,
818 account, TRUE, &negative);
819 g_value_take_string (value,
string);
821 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_CLEARED:
822 g_value_init (value, G_TYPE_STRING);
823 string = gnc_ui_account_get_print_balance (xaccAccountGetClearedBalanceInCurrency,
824 account, TRUE, &negative);
825 gnc_tree_model_account_set_color (model, negative, value);
829 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED:
830 g_value_init (value, G_TYPE_STRING);
831 string = gnc_ui_account_get_print_balance (xaccAccountGetReconciledBalanceInCurrency,
832 account, TRUE, &negative);
833 g_value_take_string (value,
string);
835 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED_REPORT:
836 g_value_init (value, G_TYPE_STRING);
837 string = gnc_ui_account_get_print_report_balance (xaccAccountGetReconciledBalanceInCurrency,
838 account, TRUE, &negative);
839 g_value_take_string (value,
string);
841 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED_DATE:
842 g_value_init (value, G_TYPE_STRING);
847 case GNC_TREE_MODEL_ACCOUNT_COL_EARLIEST_DATE:
848 g_value_init (value, G_TYPE_STRING);
850 if (earliest != INT64_MAX)
854 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_RECONCILED:
855 g_value_init (value, G_TYPE_STRING);
856 string = gnc_ui_account_get_print_balance (xaccAccountGetReconciledBalanceInCurrency,
857 account, TRUE, &negative);
858 gnc_tree_model_account_set_color (model, negative, value);
862 case GNC_TREE_MODEL_ACCOUNT_COL_FUTURE_MIN:
863 g_value_init (value, G_TYPE_STRING);
864 string = gnc_ui_account_get_print_balance (xaccAccountGetProjectedMinimumBalanceInCurrency,
865 account, TRUE, &negative);
866 g_value_take_string (value,
string);
868 case GNC_TREE_MODEL_ACCOUNT_COL_FUTURE_MIN_REPORT:
869 g_value_init (value, G_TYPE_STRING);
870 string = gnc_ui_account_get_print_report_balance (xaccAccountGetProjectedMinimumBalanceInCurrency,
871 account, TRUE, &negative);
872 g_value_take_string (value,
string);
874 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_FUTURE_MIN:
875 g_value_init (value, G_TYPE_STRING);
876 string = gnc_ui_account_get_print_balance (xaccAccountGetProjectedMinimumBalanceInCurrency,
877 account, TRUE, &negative);
878 gnc_tree_model_account_set_color (model, negative, value);
882 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL:
883 g_value_init (value, G_TYPE_STRING);
884 string = gnc_ui_account_get_print_balance (xaccAccountGetBalanceInCurrency,
885 account, TRUE, &negative);
886 g_value_take_string (value,
string);
888 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL_REPORT:
889 g_value_init (value, G_TYPE_STRING);
890 string = gnc_ui_account_get_print_report_balance (xaccAccountGetBalanceInCurrency,
891 account, TRUE, &negative);
892 g_value_take_string (value,
string);
894 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_TOTAL:
895 g_value_init (value, G_TYPE_STRING);
896 string = gnc_ui_account_get_print_balance (xaccAccountGetBalanceInCurrency,
897 account, TRUE, &negative);
898 gnc_tree_model_account_set_color (model, negative, value);
901 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL_PERIOD:
902 g_value_init (value, G_TYPE_STRING);
903 string = gnc_tree_model_account_compute_period_balance (model, account, TRUE, &negative);
904 g_value_take_string (value,
string);
906 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_TOTAL_PERIOD:
907 g_value_init (value, G_TYPE_STRING);
908 string = gnc_tree_model_account_compute_period_balance (model, account, TRUE, &negative);
909 gnc_tree_model_account_set_color (model, negative, value);
913 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_ACCOUNT:
914 g_value_init (value, G_TYPE_STRING);
918 case GNC_TREE_MODEL_ACCOUNT_COL_NOTES:
919 g_value_init (value, G_TYPE_STRING);
923 case GNC_TREE_MODEL_ACCOUNT_COL_TAX_INFO:
924 g_value_init (value, G_TYPE_STRING);
925 g_value_take_string (value, gnc_ui_account_get_tax_info_string (account));
928 case GNC_TREE_MODEL_ACCOUNT_COL_TAX_INFO_SUB_ACCT:
929 g_value_init (value, G_TYPE_STRING);
930 g_value_take_string (value, gnc_ui_account_get_tax_info_sub_acct_string (account));
933 case GNC_TREE_MODEL_ACCOUNT_COL_LASTNUM:
934 g_value_init (value, G_TYPE_STRING);
938 case GNC_TREE_MODEL_ACCOUNT_COL_HIDDEN:
939 g_value_init (value, G_TYPE_BOOLEAN);
943 case GNC_TREE_MODEL_ACCOUNT_COL_PLACEHOLDER:
944 g_value_init (value, G_TYPE_BOOLEAN);
948 case GNC_TREE_MODEL_ACCOUNT_COL_OPENING_BALANCE:
949 g_value_init (value, G_TYPE_BOOLEAN);
954 g_assert_not_reached ();
959 gnc_tree_model_account_set_cached_value (model, account, column, value);
965 gnc_tree_model_account_iter_next (GtkTreeModel *tree_model,
968 GncTreeModelAccount *model = GNC_TREE_MODEL_ACCOUNT(tree_model);
972 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(model), FALSE);
973 g_return_val_if_fail (iter != NULL, FALSE);
974 g_return_val_if_fail (iter->user_data != NULL, FALSE);
975 g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
977 ENTER(
"model %p, iter %s", tree_model, iter_to_string (iter));
979 parent = (
Account *) iter->user_data2;
988 i = GPOINTER_TO_INT(iter->user_data3);
997 iter->user_data = account;
998 iter->user_data2 = parent;
999 iter->user_data3 = GINT_TO_POINTER(i + 1);
1001 LEAVE(
"iter %s", iter_to_string (iter));
1006 gnc_tree_model_account_iter_children (GtkTreeModel *tree_model,
1008 GtkTreeIter *parent_iter)
1010 GncTreeModelAccount *model;
1013 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), FALSE);
1014 ENTER(
"model %p, iter %p (to be filed in), parent %s",
1015 tree_model, iter, (parent_iter ? iter_to_string (parent_iter) :
"(null)"));
1017 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1019 if (model->root == NULL)
1022 LEAVE(
"failed (no root)");
1029 iter->user_data = model->root;
1030 iter->user_data2 = NULL;
1031 iter->user_data3 = GINT_TO_POINTER(0);
1032 iter->stamp = model->stamp;
1033 LEAVE(
"iter (2) %s", iter_to_string (iter));
1041 parent = (
Account *)parent_iter->user_data;
1044 if (account == NULL)
1047 LEAVE(
"failed (child account is null)");
1051 iter->user_data = account;
1052 iter->user_data2 = parent;
1053 iter->user_data3 = GINT_TO_POINTER(0);
1054 iter->stamp = model->stamp;
1055 LEAVE(
"iter (3) %s", iter_to_string (iter));
1060 gnc_tree_model_account_iter_has_child (GtkTreeModel *tree_model,
1063 GncTreeModelAccount *model;
1066 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), FALSE);
1068 ENTER(
"model %p, iter %s", tree_model, iter_to_string (iter));
1070 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1076 account = (
Account *) iter->user_data;
1088 gnc_tree_model_account_iter_n_children (GtkTreeModel *tree_model,
1091 GncTreeModelAccount *model;
1094 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), FALSE);
1095 ENTER(
"model %p, iter %s", tree_model, iter_to_string (iter));
1097 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1103 LEAVE(
"count is 1");
1112 LEAVE(
"count is %d", num);
1117 gnc_tree_model_account_iter_nth_child (GtkTreeModel *tree_model,
1119 GtkTreeIter *parent_iter,
1122 GncTreeModelAccount *model;
1127 gchar *parent_string;
1128 parent_string = g_strdup (iter_to_string (parent_iter));
1129 ENTER(
"model %p, iter %s, parent_iter %s, n %d",
1130 tree_model, iter_to_string (iter),
1132 g_free (parent_string);
1136 ENTER(
"model %p, iter %s, parent_iter (null), n %d",
1137 tree_model, iter_to_string (iter), n);
1141 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1148 LEAVE(
"bad root index");
1152 iter->user_data = model->root;
1153 iter->user_data2 = NULL;
1154 iter->user_data3 = GINT_TO_POINTER(0);
1155 iter->stamp = model->stamp;
1156 LEAVE(
"root %s", iter_to_string (iter));
1163 parent = (
Account *)parent_iter->user_data;
1165 if (account == NULL)
1168 LEAVE(
"failed (2)");
1172 iter->user_data = account;
1173 iter->user_data2 = parent;
1174 iter->user_data3 = GINT_TO_POINTER(n);
1175 iter->stamp = model->stamp;
1176 LEAVE(
"iter (2) %s", iter_to_string (iter));
1181 gnc_tree_model_account_iter_parent (GtkTreeModel *tree_model,
1185 GncTreeModelAccount *model;
1191 gchar *child_string;
1193 child_string = g_strdup (iter_to_string (child));
1194 ENTER(
"model %p, iter %s, child %s",
1195 tree_model, iter_to_string (iter),
1197 g_free (child_string);
1201 ENTER(
"model %p, iter %s, child (null)",
1202 tree_model, iter_to_string (iter));
1206 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1212 account = (
Account *) child->user_data;
1214 if (account == NULL)
1218 LEAVE(
"failed (1)");
1232 iter->user_data = account;
1233 iter->user_data2 = parent;
1234 iter->user_data3 = GINT_TO_POINTER(i);
1235 iter->stamp = model->stamp;
1236 LEAVE(
"iter (2) %s", iter_to_string (iter));
1253 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(model), NULL);
1254 g_return_val_if_fail (iter != NULL, NULL);
1255 g_return_val_if_fail (iter->user_data != NULL, NULL);
1256 g_return_val_if_fail (iter->stamp == model->stamp, NULL);
1258 return (
Account *) iter->user_data;
1274 ENTER(
"model %p, account %p, iter %p", model, account, iter);
1279 iter->user_data = account;
1280 iter->stamp = model->stamp;
1282 if (account == model->root)
1284 iter->user_data2 = NULL;
1285 iter->user_data3 = GINT_TO_POINTER(0);
1286 LEAVE(
"Matched root");
1292 LEAVE(
"Root doesn't match");
1298 iter->user_data2 = parent;
1299 iter->user_data3 = GINT_TO_POINTER(i);
1300 LEAVE(
"iter %s", iter_to_string (iter));
1313 GtkTreeIter tree_iter;
1314 GtkTreePath *tree_path;
1316 ENTER(
"model %p, account %p", model, account);
1327 tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &tree_iter);
1330 gchar *path_string = gtk_tree_path_to_string (tree_path);
1331 LEAVE(
"path (2) %s", path_string);
1332 g_free (path_string);
1346 increment_stamp (GncTreeModelAccount *model)
1349 while (!model->stamp);
1353 propagate_change (GtkTreeModel *model, GtkTreePath *path, gint toggle_if_num)
1358 if (!gtk_tree_path_up (path))
1362 if (gtk_tree_path_get_depth (path) == 0)
1366 if (gtk_tree_model_get_iter (model, &iter, path))
1368 gtk_tree_model_row_changed (model, path, &iter);
1369 if (gtk_tree_model_iter_n_children (model, &iter) == toggle_if_num)
1370 gtk_tree_model_row_has_child_toggled (model, path, &iter);
1374 while (gtk_tree_path_up (path) && gtk_tree_path_get_depth (path) > 0 &&
1375 gtk_tree_model_get_iter (model, &iter, path))
1377 gtk_tree_model_row_changed (model, path, &iter);
1410 gnc_tree_model_account_event_handler (
QofInstance *entity,
1412 GncTreeModelAccount *model,
1415 const gchar *parent_name;
1416 GtkTreePath *path = NULL;
1420 g_return_if_fail (model);
1422 if (!GNC_IS_ACCOUNT(entity))
1425 ENTER(
"entity %p of type %d, model %p, event_data %p",
1426 entity, event_type, model, ed);
1428 account = GNC_ACCOUNT(entity);
1430 if (gnc_account_get_book (account) != model->book)
1432 LEAVE(
"not in this book");
1437 LEAVE(
"not in this model");
1449 DEBUG(
"can't generate path");
1452 increment_stamp (model);
1453 if (!gnc_tree_model_account_get_iter (GTK_TREE_MODEL(model), &iter, path))
1455 DEBUG(
"can't generate iter");
1458 gtk_tree_model_row_inserted (GTK_TREE_MODEL(model), path, &iter);
1459 propagate_change (GTK_TREE_MODEL(model), path, 1);
1462 case QOF_EVENT_REMOVE:
1465 parent = ed->node ? GNC_ACCOUNT(ed->node) : model->root;
1467 DEBUG(
"remove child %d of account %p (%s)", ed->idx, parent, parent_name);
1471 DEBUG(
"can't generate path");
1474 increment_stamp (model);
1475 gtk_tree_path_append_index (path, ed->idx);
1476 gtk_tree_model_row_deleted (GTK_TREE_MODEL(model), path);
1477 propagate_change (GTK_TREE_MODEL(model), path, 0);
1480 case QOF_EVENT_MODIFY:
1483 gnc_tree_model_account_clear_cached_values(model, account);
1488 DEBUG(
"can't generate path");
1491 if (!gnc_tree_model_account_get_iter (GTK_TREE_MODEL(model), &iter, path))
1493 DEBUG(
"can't generate iter");
1496 gtk_tree_model_row_changed (GTK_TREE_MODEL(model), path, &iter);
1497 propagate_change (GTK_TREE_MODEL(model), path, -1);
1501 gnc_tree_model_account_clear_cached_values(model, account);
1503 LEAVE(
"unknown event type");
1508 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.
The instance data structure for an account tree model.
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...
GncTreeModel gnc_tree_model
The parent object data.
#define DEBUG(format, args...)
Print a debugging message.
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.
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.
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.
time64 gnc_account_get_earliest_date(const Account *account)
Returns the date of the earliest split in the account, or INT64_MAX.
General utilities for dealing with accounting periods.
void qof_event_unregister_handler(gint handler_id)
Unregister an event handler.
int stamp
The state of the model.
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
Retrieve the full name for the specified commodity.
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
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
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.
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.