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"
49static QofLogModule log_module = GNC_MOD_GUI;
52static void gnc_tree_model_account_finalize (GObject *
object);
53static void gnc_tree_model_account_dispose (GObject *
object);
56static void gnc_tree_model_account_tree_model_init (GtkTreeModelIface *iface);
57static GtkTreeModelFlags gnc_tree_model_account_get_flags (GtkTreeModel *tree_model);
58static int gnc_tree_model_account_get_n_columns (GtkTreeModel *tree_model);
59static GType gnc_tree_model_account_get_column_type (GtkTreeModel *tree_model,
61static gboolean gnc_tree_model_account_get_iter (GtkTreeModel *tree_model,
64static GtkTreePath *gnc_tree_model_account_get_path (GtkTreeModel *tree_model,
66static void gnc_tree_model_account_get_value (GtkTreeModel *tree_model,
70static gboolean gnc_tree_model_account_iter_next (GtkTreeModel *tree_model,
72static gboolean gnc_tree_model_account_iter_children (GtkTreeModel *tree_model,
75static gboolean gnc_tree_model_account_iter_has_child (GtkTreeModel *tree_model,
77static int gnc_tree_model_account_iter_n_children (GtkTreeModel *tree_model,
79static gboolean gnc_tree_model_account_iter_nth_child (GtkTreeModel *tree_model,
83static gboolean gnc_tree_model_account_iter_parent (GtkTreeModel *tree_model,
88static 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;
108G_DEFINE_TYPE_WITH_CODE (GncTreeModelAccount,
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))
125gnc_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;
153gnc_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;
165gnc_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,
200gnc_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);
218gnc_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
294iter_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)");
327gnc_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;
343static GtkTreeModelFlags
344gnc_tree_model_account_get_flags (GtkTreeModel *tree_model)
350gnc_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;
358gnc_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;
416gnc_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));
471gnc_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);
522gnc_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);
533gnc_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);
567row_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);
589clear_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);
619gnc_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);
639gnc_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);
665gnc_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));
686gnc_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);
965gnc_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));
1006gnc_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));
1060gnc_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;
1088gnc_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);
1117gnc_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));
1181gnc_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);
1346increment_stamp (GncTreeModelAccount *model)
1349 while (!model->stamp);
1353propagate_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);
1410gnc_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 handling public routines.
General utilities for dealing with accounting periods.
Commodity handling public routines.
All type declarations for the whole Gnucash engine.
Additional event handling code.
Generic api to store and retrieve preferences.
GtkTreeModel implementation for gnucash account tree.
utility functions for the GnuCash UI
const char * xaccAccountGetName(const Account *acc)
Get the account's name.
const char * xaccAccountGetDescription(const Account *acc)
Get the account's description.
const char * xaccAccountGetColor(const Account *acc)
Get the account's color.
Account * gnc_account_get_root(Account *acc)
This routine returns the root account of the account tree that the specified account belongs to.
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.
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account's account type.
Account * gnc_account_nth_child(const Account *parent, gint num)
Return the n'th child account of the specified parent account.
#define xaccAccountGetGUID(X)
const char * xaccAccountGetLastNum(const Account *acc)
Get the last num field of an Account.
Account * gnc_account_get_parent(const Account *acc)
This routine returns a pointer to the parent of the specified account.
const char * xaccAccountGetNotes(const Account *acc)
Get the account's notes.
gint gnc_account_n_children(const Account *account)
Return the number of children of the specified account.
const char * xaccAccountGetCode(const Account *acc)
Get the account's accounting code.
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
Retrieve the full name for the specified commodity.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
char * qof_print_date(time64 t)
Convenience; calls through to qof_print_date_dmy_buff().
gboolean xaccAccountGetHidden(const Account *acc)
Get the "hidden" flag for an account.
gboolean xaccAccountGetPlaceholder(const Account *acc)
Get the "placeholder" flag for an account.
gboolean xaccAccountGetIsOpeningBalance(const Account *acc)
Get the "opening-balance" flag for an account.
time64 gnc_account_get_earliest_date(const Account *account)
Returns the date of the earliest split in the account, or INT64_MAX.
gboolean xaccAccountGetReconcileLastDate(const Account *acc, time64 *last_date)
DOCUMENT ME!
const char * xaccAccountGetTypeStr(GNCAccountType type)
The xaccAccountGetTypeStr() routine returns a string suitable for use in the GUI/Interface.
void qof_event_unregister_handler(gint handler_id)
Unregister an event handler.
void(* QofEventHandler)(QofInstance *ent, QofEventId event_type, gpointer handler_data, gpointer event_data)
Handler invoked when an event is generated.
gint qof_event_register_handler(QofEventHandler handler, gpointer user_data)
Register a handler for events.
gint QofEventId
Define the type of events allowed.
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
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...
const GList * gnc_gobject_tracking_get_list(const gchar *name)
Get a list of all known objects of a specified type.
Account * gnc_tree_model_account_get_account(GncTreeModelAccount *model, GtkTreeIter *iter)
Convert a model/iter pair to a gnucash account.
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.
void gnc_tree_model_account_clear_cache(GncTreeModelAccount *model)
Clear the tree model account cached values.
GtkTreeModel * gnc_tree_model_account_new(Account *root)
Create a new GtkTreeModel for manipulating gnucash accounts.
GtkTreePath * gnc_tree_model_account_get_path_from_account(GncTreeModelAccount *model, Account *account)
Convert a model/account pair into a gtk_tree_model_path.
const char * gnc_print_amount_with_bidi_ltr_isolate(gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
#define gnc_leave_return_val_if_fail(test, val)
Replacement for g_return_val_if_fail, but calls LEAVE if the test fails.
#define DEBUG(format, args...)
Print a debugging message.
#define LEAVE(format, args...)
Print a function exit debugging message.
#define ENTER(format, args...)
Print a function entry debugging message.
gboolean gnc_numeric_negative_p(gnc_numeric a)
Returns 1 if a < 0, otherwise returns 0.
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value.
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.
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.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
The instance data structure for an account tree model.
GncTreeModel gnc_tree_model
The parent object data.
int stamp
The state of the model.