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_FUTURE_MIN:
383 case GNC_TREE_MODEL_ACCOUNT_COL_FUTURE_MIN_REPORT:
384 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL:
385 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL_REPORT:
386 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL_PERIOD:
387 case GNC_TREE_MODEL_ACCOUNT_COL_NOTES:
388 case GNC_TREE_MODEL_ACCOUNT_COL_TAX_INFO:
389 case GNC_TREE_MODEL_ACCOUNT_COL_TAX_INFO_SUB_ACCT:
390 case GNC_TREE_MODEL_ACCOUNT_COL_LASTNUM:
392 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_PRESENT:
393 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_ACCOUNT:
394 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_BALANCE:
395 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_BALANCE_PERIOD:
396 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_CLEARED:
397 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_RECONCILED:
398 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_FUTURE_MIN:
399 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_TOTAL:
400 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_TOTAL_PERIOD:
401 return G_TYPE_STRING;
403 case GNC_TREE_MODEL_ACCOUNT_COL_HIDDEN:
404 case GNC_TREE_MODEL_ACCOUNT_COL_PLACEHOLDER:
405 case GNC_TREE_MODEL_ACCOUNT_COL_OPENING_BALANCE:
406 return G_TYPE_BOOLEAN;
409 g_assert_not_reached ();
410 return G_TYPE_INVALID;
415 gnc_tree_model_account_get_iter (GtkTreeModel *tree_model,
419 GncTreeModelAccount *model;
423 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), FALSE);
426 gchar *path_string = gtk_tree_path_to_string (path);
427 ENTER(
"model %p, iter %p, path %s", tree_model, iter, path_string);
428 g_free (path_string);
431 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
433 if (gtk_tree_path_get_depth (path) <= 0)
439 indices = gtk_tree_path_get_indices (path);
442 LEAVE(
"bad root index");
447 account = model->root;
448 for (i = 1; i < gtk_tree_path_get_depth (path); i++)
460 iter->stamp = model->stamp;
461 iter->user_data = account;
462 iter->user_data2 = parent;
463 iter->user_data3 = GINT_TO_POINTER(indices[i - 1]);
465 LEAVE(
"iter %s", iter_to_string (iter));
470 gnc_tree_model_account_get_path (GtkTreeModel *tree_model,
473 GncTreeModelAccount *model = GNC_TREE_MODEL_ACCOUNT(tree_model);
478 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(model), NULL);
479 g_return_val_if_fail (iter != NULL, NULL);
480 g_return_val_if_fail (iter->user_data != NULL, NULL);
481 g_return_val_if_fail (iter->stamp == model->stamp, NULL);
483 ENTER(
"model %p, iter %s", model, iter_to_string (iter));
485 if (model->root == NULL)
491 account = (
Account *) iter->user_data;
492 parent = (
Account *) iter->user_data2;
494 path = gtk_tree_path_new ();
500 gtk_tree_path_free (path);
504 gtk_tree_path_prepend_index (path, i);
510 gtk_tree_path_prepend_index (path, 0);
513 gchar *path_string = gtk_tree_path_to_string (path);
514 LEAVE(
"path (4) %s", path_string);
515 g_free (path_string);
521 gnc_tree_model_account_set_color (GncTreeModelAccount *model,
526 g_value_set_static_string (value, model->negative_color);
528 g_value_set_static_string (value, NULL);
532 gnc_tree_model_account_compute_period_balance (GncTreeModelAccount *model,
544 if (acct == model->root)
545 return g_strdup (
"");
547 t1 = gnc_accounting_period_fiscal_start ();
548 t2 = gnc_accounting_period_fiscal_end ();
551 return g_strdup (
"");
553 b3 = xaccAccountGetBalanceChangeForPeriod (acct, t1, t2, recurse);
554 if (gnc_reverse_balance (acct))
560 print_info = gnc_account_print_info (acct, TRUE);
566 row_changed_foreach_func (GtkTreeModel *model, GtkTreePath *path,
567 GtkTreeIter *iter, gpointer user_data)
569 gtk_tree_model_row_changed (model, path, iter);
579 g_hash_table_destroy (model->account_values_hash);
580 model->account_values_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
583 gtk_tree_model_foreach (GTK_TREE_MODEL(model), row_changed_foreach_func, NULL);
588 clear_account_cached_values (GncTreeModelAccount *model, GHashTable *hash,
Account *account)
599 GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter);
601 gtk_tree_model_row_changed (GTK_TREE_MODEL(model), path, &iter);
602 gtk_tree_path_free (path);
608 for (gint col = 0; col <= GNC_TREE_MODEL_ACCOUNT_NUM_COLUMNS; col++)
610 gchar *key = g_strdup_printf (
"%s,%d", acct_guid_str, col);
612 g_hash_table_remove (hash, key);
618 gnc_tree_model_account_clear_cached_values (GncTreeModelAccount *model,
Account *account)
623 if ((!model->account_values_hash) || (!account))
626 clear_account_cached_values (model, model->account_values_hash, account);
632 clear_account_cached_values (model, model->account_values_hash, parent);
638 gnc_tree_model_account_get_cached_value (GncTreeModelAccount *model,
Account *account,
639 gint column, gchar **cached_string)
646 if ((!model->account_values_hash) || (!account))
650 key = g_strdup_printf (
"%s,%d", acct_guid_str, column);
652 found = g_hash_table_lookup_extended (model->account_values_hash, key,
656 *cached_string = g_strdup (value);
664 gnc_tree_model_account_set_cached_value (GncTreeModelAccount *model,
Account *account,
665 gint column, GValue *value)
667 if ((!model->account_values_hash) || (!account))
671 if (G_VALUE_HOLDS_STRING(value))
674 const gchar *str = g_value_get_string (value);
678 key = g_strdup_printf (
"%s,%d", acct_guid_str, column);
680 g_hash_table_insert (model->account_values_hash, key, g_strdup (str));
685 gnc_tree_model_account_get_value (GtkTreeModel *tree_model,
690 GncTreeModelAccount *model = GNC_TREE_MODEL_ACCOUNT(tree_model);
694 gchar *cached_string = NULL;
698 g_return_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(model));
699 g_return_if_fail (iter != NULL);
700 g_return_if_fail (iter->user_data != NULL);
701 g_return_if_fail (iter->stamp == model->stamp);
703 ENTER(
"model %p, iter %s, col %d", tree_model,
704 iter_to_string (iter), column);
706 account = (
Account *) iter->user_data;
709 if (gnc_tree_model_account_get_cached_value (model, account, column, &cached_string))
711 g_value_init (value, G_TYPE_STRING);
712 g_value_take_string (value, cached_string);
713 LEAVE(
"value in cache, '%s'", cached_string);
719 case GNC_TREE_MODEL_ACCOUNT_COL_NAME:
720 g_value_init (value, G_TYPE_STRING);
721 if (account == model->root)
722 g_value_set_string (value, _(
"New top level account"));
726 case GNC_TREE_MODEL_ACCOUNT_COL_TYPE:
727 g_value_init (value, G_TYPE_STRING);
728 g_value_set_string (value,
731 case GNC_TREE_MODEL_ACCOUNT_COL_CODE:
732 g_value_init (value, G_TYPE_STRING);
735 case GNC_TREE_MODEL_ACCOUNT_COL_COMMODITY:
736 g_value_init (value, G_TYPE_STRING);
737 g_value_set_string (value,
740 case GNC_TREE_MODEL_ACCOUNT_COL_DESCRIPTION:
741 g_value_init (value, G_TYPE_STRING);
745 case GNC_TREE_MODEL_ACCOUNT_COL_PRESENT:
746 g_value_init (value, G_TYPE_STRING);
747 string = gnc_ui_account_get_print_balance (xaccAccountGetPresentBalanceInCurrency,
748 account, TRUE, &negative);
749 g_value_take_string (value,
string);
751 case GNC_TREE_MODEL_ACCOUNT_COL_PRESENT_REPORT:
752 g_value_init (value, G_TYPE_STRING);
753 string = gnc_ui_account_get_print_report_balance (xaccAccountGetPresentBalanceInCurrency,
754 account, TRUE, &negative);
755 g_value_take_string (value,
string);
757 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_PRESENT:
758 g_value_init (value, G_TYPE_STRING);
759 string = gnc_ui_account_get_print_balance (xaccAccountGetPresentBalanceInCurrency,
760 account, TRUE, &negative);
761 gnc_tree_model_account_set_color (model, negative, value);
765 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE:
766 g_value_init (value, G_TYPE_STRING);
767 string = gnc_ui_account_get_print_balance (xaccAccountGetBalanceInCurrency,
768 account, FALSE, &negative);
769 g_value_take_string (value,
string);
771 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_REPORT:
772 g_value_init (value, G_TYPE_STRING);
773 string = gnc_ui_account_get_print_report_balance (xaccAccountGetBalanceInCurrency,
774 account, FALSE, &negative);
775 g_value_take_string (value,
string);
777 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_BALANCE:
778 g_value_init (value, G_TYPE_STRING);
779 string = gnc_ui_account_get_print_balance (xaccAccountGetBalanceInCurrency,
780 account, FALSE, &negative);
781 gnc_tree_model_account_set_color (model, negative, value);
784 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_PERIOD:
785 g_value_init (value, G_TYPE_STRING);
786 string = gnc_tree_model_account_compute_period_balance (model, account, FALSE, &negative);
787 g_value_take_string (value,
string);
789 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_BALANCE_PERIOD:
790 g_value_init (value, G_TYPE_STRING);
791 string = gnc_tree_model_account_compute_period_balance (model, account, FALSE, &negative);
792 gnc_tree_model_account_set_color (model, negative, value);
796 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_LIMIT:
797 g_value_init (value, G_TYPE_STRING);
798 string = gnc_ui_account_get_balance_limit_icon_name (account);
799 g_value_take_string (value,
string);
802 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_LIMIT_EXPLANATION:
803 g_value_init (value, G_TYPE_STRING);
804 string = gnc_ui_account_get_balance_limit_explanation (account);
805 g_value_take_string (value,
string);
808 case GNC_TREE_MODEL_ACCOUNT_COL_CLEARED:
809 g_value_init (value, G_TYPE_STRING);
810 string = gnc_ui_account_get_print_balance (xaccAccountGetClearedBalanceInCurrency,
811 account, TRUE, &negative);
812 g_value_take_string (value,
string);
814 case GNC_TREE_MODEL_ACCOUNT_COL_CLEARED_REPORT:
815 g_value_init (value, G_TYPE_STRING);
816 string = gnc_ui_account_get_print_report_balance (xaccAccountGetClearedBalanceInCurrency,
817 account, TRUE, &negative);
818 g_value_take_string (value,
string);
820 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_CLEARED:
821 g_value_init (value, G_TYPE_STRING);
822 string = gnc_ui_account_get_print_balance (xaccAccountGetClearedBalanceInCurrency,
823 account, TRUE, &negative);
824 gnc_tree_model_account_set_color (model, negative, value);
828 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED:
829 g_value_init (value, G_TYPE_STRING);
830 string = gnc_ui_account_get_print_balance (xaccAccountGetReconciledBalanceInCurrency,
831 account, TRUE, &negative);
832 g_value_take_string (value,
string);
834 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED_REPORT:
835 g_value_init (value, G_TYPE_STRING);
836 string = gnc_ui_account_get_print_report_balance (xaccAccountGetReconciledBalanceInCurrency,
837 account, TRUE, &negative);
838 g_value_take_string (value,
string);
840 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED_DATE:
841 g_value_init (value, G_TYPE_STRING);
846 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_RECONCILED:
847 g_value_init (value, G_TYPE_STRING);
848 string = gnc_ui_account_get_print_balance (xaccAccountGetReconciledBalanceInCurrency,
849 account, TRUE, &negative);
850 gnc_tree_model_account_set_color (model, negative, value);
854 case GNC_TREE_MODEL_ACCOUNT_COL_FUTURE_MIN:
855 g_value_init (value, G_TYPE_STRING);
856 string = gnc_ui_account_get_print_balance (xaccAccountGetProjectedMinimumBalanceInCurrency,
857 account, TRUE, &negative);
858 g_value_take_string (value,
string);
860 case GNC_TREE_MODEL_ACCOUNT_COL_FUTURE_MIN_REPORT:
861 g_value_init (value, G_TYPE_STRING);
862 string = gnc_ui_account_get_print_report_balance (xaccAccountGetProjectedMinimumBalanceInCurrency,
863 account, TRUE, &negative);
864 g_value_take_string (value,
string);
866 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_FUTURE_MIN:
867 g_value_init (value, G_TYPE_STRING);
868 string = gnc_ui_account_get_print_balance (xaccAccountGetProjectedMinimumBalanceInCurrency,
869 account, TRUE, &negative);
870 gnc_tree_model_account_set_color (model, negative, value);
874 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL:
875 g_value_init (value, G_TYPE_STRING);
876 string = gnc_ui_account_get_print_balance (xaccAccountGetBalanceInCurrency,
877 account, TRUE, &negative);
878 g_value_take_string (value,
string);
880 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL_REPORT:
881 g_value_init (value, G_TYPE_STRING);
882 string = gnc_ui_account_get_print_report_balance (xaccAccountGetBalanceInCurrency,
883 account, TRUE, &negative);
884 g_value_take_string (value,
string);
886 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_TOTAL:
887 g_value_init (value, G_TYPE_STRING);
888 string = gnc_ui_account_get_print_balance (xaccAccountGetBalanceInCurrency,
889 account, TRUE, &negative);
890 gnc_tree_model_account_set_color (model, negative, value);
893 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL_PERIOD:
894 g_value_init (value, G_TYPE_STRING);
895 string = gnc_tree_model_account_compute_period_balance (model, account, TRUE, &negative);
896 g_value_take_string (value,
string);
898 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_TOTAL_PERIOD:
899 g_value_init (value, G_TYPE_STRING);
900 string = gnc_tree_model_account_compute_period_balance (model, account, TRUE, &negative);
901 gnc_tree_model_account_set_color (model, negative, value);
905 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_ACCOUNT:
906 g_value_init (value, G_TYPE_STRING);
910 case GNC_TREE_MODEL_ACCOUNT_COL_NOTES:
911 g_value_init (value, G_TYPE_STRING);
915 case GNC_TREE_MODEL_ACCOUNT_COL_TAX_INFO:
916 g_value_init (value, G_TYPE_STRING);
917 g_value_take_string (value, gnc_ui_account_get_tax_info_string (account));
920 case GNC_TREE_MODEL_ACCOUNT_COL_TAX_INFO_SUB_ACCT:
921 g_value_init (value, G_TYPE_STRING);
922 g_value_take_string (value, gnc_ui_account_get_tax_info_sub_acct_string (account));
925 case GNC_TREE_MODEL_ACCOUNT_COL_LASTNUM:
926 g_value_init (value, G_TYPE_STRING);
930 case GNC_TREE_MODEL_ACCOUNT_COL_HIDDEN:
931 g_value_init (value, G_TYPE_BOOLEAN);
935 case GNC_TREE_MODEL_ACCOUNT_COL_PLACEHOLDER:
936 g_value_init (value, G_TYPE_BOOLEAN);
940 case GNC_TREE_MODEL_ACCOUNT_COL_OPENING_BALANCE:
941 g_value_init (value, G_TYPE_BOOLEAN);
946 g_assert_not_reached ();
951 gnc_tree_model_account_set_cached_value (model, account, column, value);
957 gnc_tree_model_account_iter_next (GtkTreeModel *tree_model,
960 GncTreeModelAccount *model = GNC_TREE_MODEL_ACCOUNT(tree_model);
964 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(model), FALSE);
965 g_return_val_if_fail (iter != NULL, FALSE);
966 g_return_val_if_fail (iter->user_data != NULL, FALSE);
967 g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
969 ENTER(
"model %p, iter %s", tree_model, iter_to_string (iter));
971 parent = (
Account *) iter->user_data2;
980 i = GPOINTER_TO_INT(iter->user_data3);
989 iter->user_data = account;
990 iter->user_data2 = parent;
991 iter->user_data3 = GINT_TO_POINTER(i + 1);
993 LEAVE(
"iter %s", iter_to_string (iter));
998 gnc_tree_model_account_iter_children (GtkTreeModel *tree_model,
1000 GtkTreeIter *parent_iter)
1002 GncTreeModelAccount *model;
1005 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), FALSE);
1006 ENTER(
"model %p, iter %p (to be filed in), parent %s",
1007 tree_model, iter, (parent_iter ? iter_to_string (parent_iter) :
"(null)"));
1009 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1011 if (model->root == NULL)
1014 LEAVE(
"failed (no root)");
1021 iter->user_data = model->root;
1022 iter->user_data2 = NULL;
1023 iter->user_data3 = GINT_TO_POINTER(0);
1024 iter->stamp = model->stamp;
1025 LEAVE(
"iter (2) %s", iter_to_string (iter));
1033 parent = (
Account *)parent_iter->user_data;
1036 if (account == NULL)
1039 LEAVE(
"failed (child account is null)");
1043 iter->user_data = account;
1044 iter->user_data2 = parent;
1045 iter->user_data3 = GINT_TO_POINTER(0);
1046 iter->stamp = model->stamp;
1047 LEAVE(
"iter (3) %s", iter_to_string (iter));
1052 gnc_tree_model_account_iter_has_child (GtkTreeModel *tree_model,
1055 GncTreeModelAccount *model;
1058 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), FALSE);
1060 ENTER(
"model %p, iter %s", tree_model, iter_to_string (iter));
1062 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1068 account = (
Account *) iter->user_data;
1080 gnc_tree_model_account_iter_n_children (GtkTreeModel *tree_model,
1083 GncTreeModelAccount *model;
1086 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), FALSE);
1087 ENTER(
"model %p, iter %s", tree_model, iter_to_string (iter));
1089 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1095 LEAVE(
"count is 1");
1104 LEAVE(
"count is %d", num);
1109 gnc_tree_model_account_iter_nth_child (GtkTreeModel *tree_model,
1111 GtkTreeIter *parent_iter,
1114 GncTreeModelAccount *model;
1119 gchar *parent_string;
1120 parent_string = g_strdup (iter_to_string (parent_iter));
1121 ENTER(
"model %p, iter %s, parent_iter %s, n %d",
1122 tree_model, iter_to_string (iter),
1124 g_free (parent_string);
1128 ENTER(
"model %p, iter %s, parent_iter (null), n %d",
1129 tree_model, iter_to_string (iter), n);
1133 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1140 LEAVE(
"bad root index");
1144 iter->user_data = model->root;
1145 iter->user_data2 = NULL;
1146 iter->user_data3 = GINT_TO_POINTER(0);
1147 iter->stamp = model->stamp;
1148 LEAVE(
"root %s", iter_to_string (iter));
1155 parent = (
Account *)parent_iter->user_data;
1157 if (account == NULL)
1160 LEAVE(
"failed (2)");
1164 iter->user_data = account;
1165 iter->user_data2 = parent;
1166 iter->user_data3 = GINT_TO_POINTER(n);
1167 iter->stamp = model->stamp;
1168 LEAVE(
"iter (2) %s", iter_to_string (iter));
1173 gnc_tree_model_account_iter_parent (GtkTreeModel *tree_model,
1177 GncTreeModelAccount *model;
1183 gchar *child_string;
1185 child_string = g_strdup (iter_to_string (child));
1186 ENTER(
"model %p, iter %s, child %s",
1187 tree_model, iter_to_string (iter),
1189 g_free (child_string);
1193 ENTER(
"model %p, iter %s, child (null)",
1194 tree_model, iter_to_string (iter));
1198 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1204 account = (
Account *) child->user_data;
1206 if (account == NULL)
1210 LEAVE(
"failed (1)");
1224 iter->user_data = account;
1225 iter->user_data2 = parent;
1226 iter->user_data3 = GINT_TO_POINTER(i);
1227 iter->stamp = model->stamp;
1228 LEAVE(
"iter (2) %s", iter_to_string (iter));
1245 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(model), NULL);
1246 g_return_val_if_fail (iter != NULL, NULL);
1247 g_return_val_if_fail (iter->user_data != NULL, NULL);
1248 g_return_val_if_fail (iter->stamp == model->stamp, NULL);
1250 return (
Account *) iter->user_data;
1266 ENTER(
"model %p, account %p, iter %p", model, account, iter);
1271 iter->user_data = account;
1272 iter->stamp = model->stamp;
1274 if (account == model->root)
1276 iter->user_data2 = NULL;
1277 iter->user_data3 = GINT_TO_POINTER(0);
1278 LEAVE(
"Matched root");
1284 LEAVE(
"Root doesn't match");
1290 iter->user_data2 = parent;
1291 iter->user_data3 = GINT_TO_POINTER(i);
1292 LEAVE(
"iter %s", iter_to_string (iter));
1305 GtkTreeIter tree_iter;
1306 GtkTreePath *tree_path;
1308 ENTER(
"model %p, account %p", model, account);
1319 tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &tree_iter);
1322 gchar *path_string = gtk_tree_path_to_string (tree_path);
1323 LEAVE(
"path (2) %s", path_string);
1324 g_free (path_string);
1338 increment_stamp (GncTreeModelAccount *model)
1341 while (!model->stamp);
1345 propagate_change (GtkTreeModel *model, GtkTreePath *path, gint toggle_if_num)
1350 if (!gtk_tree_path_up (path))
1354 if (gtk_tree_path_get_depth (path) == 0)
1358 if (gtk_tree_model_get_iter (model, &iter, path))
1360 gtk_tree_model_row_changed (model, path, &iter);
1361 if (gtk_tree_model_iter_n_children (model, &iter) == toggle_if_num)
1362 gtk_tree_model_row_has_child_toggled (model, path, &iter);
1366 while (gtk_tree_path_up (path) && gtk_tree_path_get_depth (path) > 0 &&
1367 gtk_tree_model_get_iter (model, &iter, path))
1369 gtk_tree_model_row_changed (model, path, &iter);
1402 gnc_tree_model_account_event_handler (
QofInstance *entity,
1404 GncTreeModelAccount *model,
1407 const gchar *parent_name;
1408 GtkTreePath *path = NULL;
1412 g_return_if_fail (model);
1414 if (!GNC_IS_ACCOUNT(entity))
1417 ENTER(
"entity %p of type %d, model %p, event_data %p",
1418 entity, event_type, model, ed);
1420 account = GNC_ACCOUNT(entity);
1422 if (gnc_account_get_book (account) != model->book)
1424 LEAVE(
"not in this book");
1429 LEAVE(
"not in this model");
1441 DEBUG(
"can't generate path");
1444 increment_stamp (model);
1445 if (!gnc_tree_model_account_get_iter (GTK_TREE_MODEL(model), &iter, path))
1447 DEBUG(
"can't generate iter");
1450 gtk_tree_model_row_inserted (GTK_TREE_MODEL(model), path, &iter);
1451 propagate_change (GTK_TREE_MODEL(model), path, 1);
1454 case QOF_EVENT_REMOVE:
1457 parent = ed->node ? GNC_ACCOUNT(ed->node) : model->root;
1459 DEBUG(
"remove child %d of account %p (%s)", ed->idx, parent, parent_name);
1463 DEBUG(
"can't generate path");
1466 increment_stamp (model);
1467 gtk_tree_path_append_index (path, ed->idx);
1468 gtk_tree_model_row_deleted (GTK_TREE_MODEL(model), path);
1469 propagate_change (GTK_TREE_MODEL(model), path, 0);
1472 case QOF_EVENT_MODIFY:
1475 gnc_tree_model_account_clear_cached_values(model, account);
1480 DEBUG(
"can't generate path");
1483 if (!gnc_tree_model_account_get_iter (GTK_TREE_MODEL(model), &iter, path))
1485 DEBUG(
"can't generate iter");
1488 gtk_tree_model_row_changed (GTK_TREE_MODEL(model), path, &iter);
1489 propagate_change (GTK_TREE_MODEL(model), path, -1);
1493 gnc_tree_model_account_clear_cached_values(model, account);
1495 LEAVE(
"unknown event type");
1500 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.
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.