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,
245 G_OBJECT_CLASS(gnc_tree_model_account_parent_class)->dispose (
object);
257 GncTreeModelAccount *model;
260 ENTER(
"root %p", root);
262 for ( ; item; item = g_list_next (item))
264 model = (GncTreeModelAccount *)item->data;
265 if (model->root == root)
267 g_object_ref (G_OBJECT(model));
268 LEAVE(
"returning existing model %p", model);
269 return GTK_TREE_MODEL(model);
273 model = g_object_new (GNC_TYPE_TREE_MODEL_ACCOUNT, NULL);
275 model->book = gnc_get_current_book();
281 LEAVE(
"model %p", model);
282 return GTK_TREE_MODEL(model);
290 #define ITER_STRING_LEN 128 293 iter_to_string (GtkTreeIter *iter)
295 #ifdef G_THREADS_ENABLED 296 static GPrivate gtmits_buffer_key = G_PRIVATE_INIT(g_free);
299 string = g_private_get (>mits_buffer_key);
302 string = g_malloc(ITER_STRING_LEN + 1);
303 g_private_set (>mits_buffer_key,
string);
306 static char string[ITER_STRING_LEN + 1];
310 snprintf (
string, ITER_STRING_LEN,
311 "[stamp:%x data:%p (%s), %p, %d]",
312 iter->stamp, iter->user_data,
314 iter->user_data2, GPOINTER_TO_INT(iter->user_data3));
316 strcpy (
string,
"(null)");
326 gnc_tree_model_account_tree_model_init (GtkTreeModelIface *iface)
328 iface->get_flags = gnc_tree_model_account_get_flags;
329 iface->get_n_columns = gnc_tree_model_account_get_n_columns;
330 iface->get_column_type = gnc_tree_model_account_get_column_type;
331 iface->get_iter = gnc_tree_model_account_get_iter;
332 iface->get_path = gnc_tree_model_account_get_path;
333 iface->get_value = gnc_tree_model_account_get_value;
334 iface->iter_next = gnc_tree_model_account_iter_next;
335 iface->iter_children = gnc_tree_model_account_iter_children;
336 iface->iter_has_child = gnc_tree_model_account_iter_has_child;
337 iface->iter_n_children = gnc_tree_model_account_iter_n_children;
338 iface->iter_nth_child = gnc_tree_model_account_iter_nth_child;
339 iface->iter_parent = gnc_tree_model_account_iter_parent;
342 static GtkTreeModelFlags
343 gnc_tree_model_account_get_flags (GtkTreeModel *tree_model)
349 gnc_tree_model_account_get_n_columns (GtkTreeModel *tree_model)
351 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), -1);
353 return GNC_TREE_MODEL_ACCOUNT_NUM_COLUMNS;
357 gnc_tree_model_account_get_column_type (GtkTreeModel *tree_model,
int index)
359 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT (tree_model), G_TYPE_INVALID);
360 g_return_val_if_fail ((index < GNC_TREE_MODEL_ACCOUNT_NUM_COLUMNS) && (index >= 0), G_TYPE_INVALID);
364 case GNC_TREE_MODEL_ACCOUNT_COL_NAME:
365 case GNC_TREE_MODEL_ACCOUNT_COL_TYPE:
366 case GNC_TREE_MODEL_ACCOUNT_COL_COMMODITY:
367 case GNC_TREE_MODEL_ACCOUNT_COL_CODE:
368 case GNC_TREE_MODEL_ACCOUNT_COL_DESCRIPTION:
369 case GNC_TREE_MODEL_ACCOUNT_COL_PRESENT:
370 case GNC_TREE_MODEL_ACCOUNT_COL_PRESENT_REPORT:
371 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE:
372 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_REPORT:
373 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_PERIOD:
374 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_LIMIT:
375 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_LIMIT_EXPLANATION:
376 case GNC_TREE_MODEL_ACCOUNT_COL_CLEARED:
377 case GNC_TREE_MODEL_ACCOUNT_COL_CLEARED_REPORT:
378 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED:
379 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED_REPORT:
380 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED_DATE:
381 case GNC_TREE_MODEL_ACCOUNT_COL_FUTURE_MIN:
382 case GNC_TREE_MODEL_ACCOUNT_COL_FUTURE_MIN_REPORT:
383 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL:
384 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL_REPORT:
385 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL_PERIOD:
386 case GNC_TREE_MODEL_ACCOUNT_COL_NOTES:
387 case GNC_TREE_MODEL_ACCOUNT_COL_TAX_INFO:
388 case GNC_TREE_MODEL_ACCOUNT_COL_TAX_INFO_SUB_ACCT:
389 case GNC_TREE_MODEL_ACCOUNT_COL_LASTNUM:
391 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_PRESENT:
392 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_ACCOUNT:
393 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_BALANCE:
394 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_BALANCE_PERIOD:
395 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_CLEARED:
396 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_RECONCILED:
397 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_FUTURE_MIN:
398 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_TOTAL:
399 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_TOTAL_PERIOD:
400 return G_TYPE_STRING;
402 case GNC_TREE_MODEL_ACCOUNT_COL_HIDDEN:
403 case GNC_TREE_MODEL_ACCOUNT_COL_PLACEHOLDER:
404 case GNC_TREE_MODEL_ACCOUNT_COL_OPENING_BALANCE:
405 return G_TYPE_BOOLEAN;
408 g_assert_not_reached ();
409 return G_TYPE_INVALID;
414 gnc_tree_model_account_get_iter (GtkTreeModel *tree_model,
418 GncTreeModelAccount *model;
422 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), FALSE);
425 gchar *path_string = gtk_tree_path_to_string (path);
426 ENTER(
"model %p, iter %p, path %s", tree_model, iter, path_string);
427 g_free (path_string);
430 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
432 if (gtk_tree_path_get_depth (path) <= 0)
438 indices = gtk_tree_path_get_indices (path);
441 LEAVE(
"bad root index");
446 account = model->root;
447 for (i = 1; i < gtk_tree_path_get_depth (path); i++)
459 iter->stamp = model->stamp;
460 iter->user_data = account;
461 iter->user_data2 = parent;
462 iter->user_data3 = GINT_TO_POINTER(indices[i - 1]);
464 LEAVE(
"iter %s", iter_to_string (iter));
469 gnc_tree_model_account_get_path (GtkTreeModel *tree_model,
472 GncTreeModelAccount *model = GNC_TREE_MODEL_ACCOUNT(tree_model);
477 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(model), NULL);
478 g_return_val_if_fail (iter != NULL, NULL);
479 g_return_val_if_fail (iter->user_data != NULL, NULL);
480 g_return_val_if_fail (iter->stamp == model->stamp, NULL);
482 ENTER(
"model %p, iter %s", model, iter_to_string (iter));
484 if (model->root == NULL)
490 account = (
Account *) iter->user_data;
491 parent = (
Account *) iter->user_data2;
493 path = gtk_tree_path_new ();
499 gtk_tree_path_free (path);
503 gtk_tree_path_prepend_index (path, i);
509 gtk_tree_path_prepend_index (path, 0);
512 gchar *path_string = gtk_tree_path_to_string (path);
513 LEAVE(
"path (4) %s", path_string);
514 g_free (path_string);
520 gnc_tree_model_account_set_color (GncTreeModelAccount *model,
525 g_value_set_static_string (value, model->negative_color);
527 g_value_set_static_string (value, NULL);
531 gnc_tree_model_account_compute_period_balance (GncTreeModelAccount *model,
543 if (acct == model->root)
544 return g_strdup (
"");
546 t1 = gnc_accounting_period_fiscal_start ();
547 t2 = gnc_accounting_period_fiscal_end ();
550 return g_strdup (
"");
552 b3 = xaccAccountGetBalanceChangeForPeriod (acct, t1, t2, recurse);
553 if (gnc_reverse_balance (acct))
559 print_info = gnc_account_print_info (acct, TRUE);
565 row_changed_foreach_func (GtkTreeModel *model, GtkTreePath *path,
566 GtkTreeIter *iter, gpointer user_data)
568 gtk_tree_model_row_changed (model, path, iter);
578 g_hash_table_destroy (model->account_values_hash);
579 model->account_values_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
582 gtk_tree_model_foreach (GTK_TREE_MODEL(model), row_changed_foreach_func, NULL);
587 clear_account_cached_values (GncTreeModelAccount *model, GHashTable *hash,
Account *account)
598 GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter);
600 gtk_tree_model_row_changed (GTK_TREE_MODEL(model), path, &iter);
601 gtk_tree_path_free (path);
607 for (gint col = 0; col <= GNC_TREE_MODEL_ACCOUNT_NUM_COLUMNS; col++)
609 gchar *key = g_strdup_printf (
"%s,%d", acct_guid_str, col);
611 g_hash_table_remove (hash, key);
617 gnc_tree_model_account_clear_cached_values (GncTreeModelAccount *model,
Account *account)
622 if ((!model->account_values_hash) || (!account))
625 clear_account_cached_values (model, model->account_values_hash, account);
631 clear_account_cached_values (model, model->account_values_hash, parent);
637 gnc_tree_model_account_get_cached_value (GncTreeModelAccount *model,
Account *account,
638 gint column, gchar **cached_string)
645 if ((!model->account_values_hash) || (!account))
649 key = g_strdup_printf (
"%s,%d", acct_guid_str, column);
651 found = g_hash_table_lookup_extended (model->account_values_hash, key,
655 *cached_string = g_strdup (value);
663 gnc_tree_model_account_set_cached_value (GncTreeModelAccount *model,
Account *account,
664 gint column, GValue *value)
666 if ((!model->account_values_hash) || (!account))
670 if (G_VALUE_HOLDS_STRING(value))
673 const gchar *str = g_value_get_string (value);
677 key = g_strdup_printf (
"%s,%d", acct_guid_str, column);
679 g_hash_table_insert (model->account_values_hash, key, g_strdup (str));
684 gnc_tree_model_account_get_value (GtkTreeModel *tree_model,
689 GncTreeModelAccount *model = GNC_TREE_MODEL_ACCOUNT(tree_model);
693 gchar *cached_string = NULL;
697 g_return_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(model));
698 g_return_if_fail (iter != NULL);
699 g_return_if_fail (iter->user_data != NULL);
700 g_return_if_fail (iter->stamp == model->stamp);
702 ENTER(
"model %p, iter %s, col %d", tree_model,
703 iter_to_string (iter), column);
705 account = (
Account *) iter->user_data;
708 if (gnc_tree_model_account_get_cached_value (model, account, column, &cached_string))
710 g_value_init (value, G_TYPE_STRING);
711 g_value_take_string (value, cached_string);
712 LEAVE(
"value in cache, '%s'", cached_string);
718 case GNC_TREE_MODEL_ACCOUNT_COL_NAME:
719 g_value_init (value, G_TYPE_STRING);
720 if (account == model->root)
721 g_value_set_string (value, _(
"New top level account"));
725 case GNC_TREE_MODEL_ACCOUNT_COL_TYPE:
726 g_value_init (value, G_TYPE_STRING);
727 g_value_set_string (value,
730 case GNC_TREE_MODEL_ACCOUNT_COL_CODE:
731 g_value_init (value, G_TYPE_STRING);
734 case GNC_TREE_MODEL_ACCOUNT_COL_COMMODITY:
735 g_value_init (value, G_TYPE_STRING);
736 g_value_set_string (value,
739 case GNC_TREE_MODEL_ACCOUNT_COL_DESCRIPTION:
740 g_value_init (value, G_TYPE_STRING);
744 case GNC_TREE_MODEL_ACCOUNT_COL_PRESENT:
745 g_value_init (value, G_TYPE_STRING);
746 string = gnc_ui_account_get_print_balance (xaccAccountGetPresentBalanceInCurrency,
747 account, TRUE, &negative);
748 g_value_take_string (value,
string);
750 case GNC_TREE_MODEL_ACCOUNT_COL_PRESENT_REPORT:
751 g_value_init (value, G_TYPE_STRING);
752 string = gnc_ui_account_get_print_report_balance (xaccAccountGetPresentBalanceInCurrency,
753 account, TRUE, &negative);
754 g_value_take_string (value,
string);
756 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_PRESENT:
757 g_value_init (value, G_TYPE_STRING);
758 string = gnc_ui_account_get_print_balance (xaccAccountGetPresentBalanceInCurrency,
759 account, TRUE, &negative);
760 gnc_tree_model_account_set_color (model, negative, value);
764 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE:
765 g_value_init (value, G_TYPE_STRING);
766 string = gnc_ui_account_get_print_balance (xaccAccountGetBalanceInCurrency,
767 account, FALSE, &negative);
768 g_value_take_string (value,
string);
770 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_REPORT:
771 g_value_init (value, G_TYPE_STRING);
772 string = gnc_ui_account_get_print_report_balance (xaccAccountGetBalanceInCurrency,
773 account, FALSE, &negative);
774 g_value_take_string (value,
string);
776 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_BALANCE:
777 g_value_init (value, G_TYPE_STRING);
778 string = gnc_ui_account_get_print_balance (xaccAccountGetBalanceInCurrency,
779 account, FALSE, &negative);
780 gnc_tree_model_account_set_color (model, negative, value);
783 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_PERIOD:
784 g_value_init (value, G_TYPE_STRING);
785 string = gnc_tree_model_account_compute_period_balance (model, account, FALSE, &negative);
786 g_value_take_string (value,
string);
788 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_BALANCE_PERIOD:
789 g_value_init (value, G_TYPE_STRING);
790 string = gnc_tree_model_account_compute_period_balance (model, account, FALSE, &negative);
791 gnc_tree_model_account_set_color (model, negative, value);
795 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_LIMIT:
796 g_value_init (value, G_TYPE_STRING);
797 string = gnc_ui_account_get_balance_limit_icon_name (account);
798 g_value_take_string (value,
string);
801 case GNC_TREE_MODEL_ACCOUNT_COL_BALANCE_LIMIT_EXPLANATION:
802 g_value_init (value, G_TYPE_STRING);
803 string = gnc_ui_account_get_balance_limit_explanation (account);
804 g_value_take_string (value,
string);
807 case GNC_TREE_MODEL_ACCOUNT_COL_CLEARED:
808 g_value_init (value, G_TYPE_STRING);
809 string = gnc_ui_account_get_print_balance (xaccAccountGetClearedBalanceInCurrency,
810 account, TRUE, &negative);
811 g_value_take_string (value,
string);
813 case GNC_TREE_MODEL_ACCOUNT_COL_CLEARED_REPORT:
814 g_value_init (value, G_TYPE_STRING);
815 string = gnc_ui_account_get_print_report_balance (xaccAccountGetClearedBalanceInCurrency,
816 account, TRUE, &negative);
817 g_value_take_string (value,
string);
819 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_CLEARED:
820 g_value_init (value, G_TYPE_STRING);
821 string = gnc_ui_account_get_print_balance (xaccAccountGetClearedBalanceInCurrency,
822 account, TRUE, &negative);
823 gnc_tree_model_account_set_color (model, negative, value);
827 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED:
828 g_value_init (value, G_TYPE_STRING);
829 string = gnc_ui_account_get_print_balance (xaccAccountGetReconciledBalanceInCurrency,
830 account, TRUE, &negative);
831 g_value_take_string (value,
string);
833 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED_REPORT:
834 g_value_init (value, G_TYPE_STRING);
835 string = gnc_ui_account_get_print_report_balance (xaccAccountGetReconciledBalanceInCurrency,
836 account, TRUE, &negative);
837 g_value_take_string (value,
string);
839 case GNC_TREE_MODEL_ACCOUNT_COL_RECONCILED_DATE:
840 g_value_init (value, G_TYPE_STRING);
845 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_RECONCILED:
846 g_value_init (value, G_TYPE_STRING);
847 string = gnc_ui_account_get_print_balance (xaccAccountGetReconciledBalanceInCurrency,
848 account, TRUE, &negative);
849 gnc_tree_model_account_set_color (model, negative, value);
853 case GNC_TREE_MODEL_ACCOUNT_COL_FUTURE_MIN:
854 g_value_init (value, G_TYPE_STRING);
855 string = gnc_ui_account_get_print_balance (xaccAccountGetProjectedMinimumBalanceInCurrency,
856 account, TRUE, &negative);
857 g_value_take_string (value,
string);
859 case GNC_TREE_MODEL_ACCOUNT_COL_FUTURE_MIN_REPORT:
860 g_value_init (value, G_TYPE_STRING);
861 string = gnc_ui_account_get_print_report_balance (xaccAccountGetProjectedMinimumBalanceInCurrency,
862 account, TRUE, &negative);
863 g_value_take_string (value,
string);
865 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_FUTURE_MIN:
866 g_value_init (value, G_TYPE_STRING);
867 string = gnc_ui_account_get_print_balance (xaccAccountGetProjectedMinimumBalanceInCurrency,
868 account, TRUE, &negative);
869 gnc_tree_model_account_set_color (model, negative, value);
873 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL:
874 g_value_init (value, G_TYPE_STRING);
875 string = gnc_ui_account_get_print_balance (xaccAccountGetBalanceInCurrency,
876 account, TRUE, &negative);
877 g_value_take_string (value,
string);
879 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL_REPORT:
880 g_value_init (value, G_TYPE_STRING);
881 string = gnc_ui_account_get_print_report_balance (xaccAccountGetBalanceInCurrency,
882 account, TRUE, &negative);
883 g_value_take_string (value,
string);
885 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_TOTAL:
886 g_value_init (value, G_TYPE_STRING);
887 string = gnc_ui_account_get_print_balance (xaccAccountGetBalanceInCurrency,
888 account, TRUE, &negative);
889 gnc_tree_model_account_set_color (model, negative, value);
892 case GNC_TREE_MODEL_ACCOUNT_COL_TOTAL_PERIOD:
893 g_value_init (value, G_TYPE_STRING);
894 string = gnc_tree_model_account_compute_period_balance (model, account, TRUE, &negative);
895 g_value_take_string (value,
string);
897 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_TOTAL_PERIOD:
898 g_value_init (value, G_TYPE_STRING);
899 string = gnc_tree_model_account_compute_period_balance (model, account, TRUE, &negative);
900 gnc_tree_model_account_set_color (model, negative, value);
904 case GNC_TREE_MODEL_ACCOUNT_COL_COLOR_ACCOUNT:
905 g_value_init (value, G_TYPE_STRING);
909 case GNC_TREE_MODEL_ACCOUNT_COL_NOTES:
910 g_value_init (value, G_TYPE_STRING);
914 case GNC_TREE_MODEL_ACCOUNT_COL_TAX_INFO:
915 g_value_init (value, G_TYPE_STRING);
916 g_value_take_string (value, gnc_ui_account_get_tax_info_string (account));
919 case GNC_TREE_MODEL_ACCOUNT_COL_TAX_INFO_SUB_ACCT:
920 g_value_init (value, G_TYPE_STRING);
921 g_value_take_string (value, gnc_ui_account_get_tax_info_sub_acct_string (account));
924 case GNC_TREE_MODEL_ACCOUNT_COL_LASTNUM:
925 g_value_init (value, G_TYPE_STRING);
929 case GNC_TREE_MODEL_ACCOUNT_COL_HIDDEN:
930 g_value_init (value, G_TYPE_BOOLEAN);
934 case GNC_TREE_MODEL_ACCOUNT_COL_PLACEHOLDER:
935 g_value_init (value, G_TYPE_BOOLEAN);
939 case GNC_TREE_MODEL_ACCOUNT_COL_OPENING_BALANCE:
940 g_value_init (value, G_TYPE_BOOLEAN);
945 g_assert_not_reached ();
950 gnc_tree_model_account_set_cached_value (model, account, column, value);
956 gnc_tree_model_account_iter_next (GtkTreeModel *tree_model,
959 GncTreeModelAccount *model = GNC_TREE_MODEL_ACCOUNT(tree_model);
963 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(model), FALSE);
964 g_return_val_if_fail (iter != NULL, FALSE);
965 g_return_val_if_fail (iter->user_data != NULL, FALSE);
966 g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
968 ENTER(
"model %p, iter %s", tree_model, iter_to_string (iter));
970 parent = (
Account *) iter->user_data2;
979 i = GPOINTER_TO_INT(iter->user_data3);
988 iter->user_data = account;
989 iter->user_data2 = parent;
990 iter->user_data3 = GINT_TO_POINTER(i + 1);
992 LEAVE(
"iter %s", iter_to_string (iter));
997 gnc_tree_model_account_iter_children (GtkTreeModel *tree_model,
999 GtkTreeIter *parent_iter)
1001 GncTreeModelAccount *model;
1004 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), FALSE);
1005 ENTER(
"model %p, iter %p (to be filed in), parent %s",
1006 tree_model, iter, (parent_iter ? iter_to_string (parent_iter) :
"(null)"));
1008 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1010 if (model->root == NULL)
1013 LEAVE(
"failed (no root)");
1020 iter->user_data = model->root;
1021 iter->user_data2 = NULL;
1022 iter->user_data3 = GINT_TO_POINTER(0);
1023 iter->stamp = model->stamp;
1024 LEAVE(
"iter (2) %s", iter_to_string (iter));
1032 parent = (
Account *)parent_iter->user_data;
1035 if (account == NULL)
1038 LEAVE(
"failed (child account is null)");
1042 iter->user_data = account;
1043 iter->user_data2 = parent;
1044 iter->user_data3 = GINT_TO_POINTER(0);
1045 iter->stamp = model->stamp;
1046 LEAVE(
"iter (3) %s", iter_to_string (iter));
1051 gnc_tree_model_account_iter_has_child (GtkTreeModel *tree_model,
1054 GncTreeModelAccount *model;
1057 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), FALSE);
1059 ENTER(
"model %p, iter %s", tree_model, iter_to_string (iter));
1061 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1067 account = (
Account *) iter->user_data;
1079 gnc_tree_model_account_iter_n_children (GtkTreeModel *tree_model,
1082 GncTreeModelAccount *model;
1085 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(tree_model), FALSE);
1086 ENTER(
"model %p, iter %s", tree_model, iter_to_string (iter));
1088 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1094 LEAVE(
"count is 1");
1103 LEAVE(
"count is %d", num);
1108 gnc_tree_model_account_iter_nth_child (GtkTreeModel *tree_model,
1110 GtkTreeIter *parent_iter,
1113 GncTreeModelAccount *model;
1118 gchar *parent_string;
1119 parent_string = g_strdup (iter_to_string (parent_iter));
1120 ENTER(
"model %p, iter %s, parent_iter %s, n %d",
1121 tree_model, iter_to_string (iter),
1123 g_free (parent_string);
1127 ENTER(
"model %p, iter %s, parent_iter (null), n %d",
1128 tree_model, iter_to_string (iter), n);
1132 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1139 LEAVE(
"bad root index");
1143 iter->user_data = model->root;
1144 iter->user_data2 = NULL;
1145 iter->user_data3 = GINT_TO_POINTER(0);
1146 iter->stamp = model->stamp;
1147 LEAVE(
"root %s", iter_to_string (iter));
1154 parent = (
Account *)parent_iter->user_data;
1156 if (account == NULL)
1159 LEAVE(
"failed (2)");
1163 iter->user_data = account;
1164 iter->user_data2 = parent;
1165 iter->user_data3 = GINT_TO_POINTER(n);
1166 iter->stamp = model->stamp;
1167 LEAVE(
"iter (2) %s", iter_to_string (iter));
1172 gnc_tree_model_account_iter_parent (GtkTreeModel *tree_model,
1176 GncTreeModelAccount *model;
1182 gchar *child_string;
1184 child_string = g_strdup (iter_to_string (child));
1185 ENTER(
"model %p, iter %s, child %s",
1186 tree_model, iter_to_string (iter),
1188 g_free (child_string);
1192 ENTER(
"model %p, iter %s, child (null)",
1193 tree_model, iter_to_string (iter));
1197 model = GNC_TREE_MODEL_ACCOUNT(tree_model);
1203 account = (
Account *) child->user_data;
1205 if (account == NULL)
1209 LEAVE(
"failed (1)");
1223 iter->user_data = account;
1224 iter->user_data2 = parent;
1225 iter->user_data3 = GINT_TO_POINTER(i);
1226 iter->stamp = model->stamp;
1227 LEAVE(
"iter (2) %s", iter_to_string (iter));
1244 g_return_val_if_fail (GNC_IS_TREE_MODEL_ACCOUNT(model), NULL);
1245 g_return_val_if_fail (iter != NULL, NULL);
1246 g_return_val_if_fail (iter->user_data != NULL, NULL);
1247 g_return_val_if_fail (iter->stamp == model->stamp, NULL);
1249 return (
Account *) iter->user_data;
1265 ENTER(
"model %p, account %p, iter %p", model, account, iter);
1270 iter->user_data = account;
1271 iter->stamp = model->stamp;
1273 if (account == model->root)
1275 iter->user_data2 = NULL;
1276 iter->user_data3 = GINT_TO_POINTER(0);
1277 LEAVE(
"Matched root");
1283 LEAVE(
"Root doesn't match");
1289 iter->user_data2 = parent;
1290 iter->user_data3 = GINT_TO_POINTER(i);
1291 LEAVE(
"iter %s", iter_to_string (iter));
1304 GtkTreeIter tree_iter;
1305 GtkTreePath *tree_path;
1307 ENTER(
"model %p, account %p", model, account);
1318 tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &tree_iter);
1321 gchar *path_string = gtk_tree_path_to_string (tree_path);
1322 LEAVE(
"path (2) %s", path_string);
1323 g_free (path_string);
1337 increment_stamp (GncTreeModelAccount *model)
1340 while (!model->stamp);
1344 propagate_change (GtkTreeModel *model, GtkTreePath *path, gint toggle_if_num)
1349 if (!gtk_tree_path_up (path))
1353 if (gtk_tree_path_get_depth (path) == 0)
1357 if (gtk_tree_model_get_iter (model, &iter, path))
1359 gtk_tree_model_row_changed (model, path, &iter);
1360 if (gtk_tree_model_iter_n_children (model, &iter) == toggle_if_num)
1361 gtk_tree_model_row_has_child_toggled (model, path, &iter);
1365 while (gtk_tree_path_up (path) && gtk_tree_path_get_depth (path) > 0 &&
1366 gtk_tree_model_get_iter (model, &iter, path))
1368 gtk_tree_model_row_changed (model, path, &iter);
1401 gnc_tree_model_account_event_handler (
QofInstance *entity,
1403 GncTreeModelAccount *model,
1406 const gchar *parent_name;
1407 GtkTreePath *path = NULL;
1411 g_return_if_fail (model);
1413 if (!GNC_IS_ACCOUNT(entity))
1416 ENTER(
"entity %p of type %d, model %p, event_data %p",
1417 entity, event_type, model, ed);
1419 account = GNC_ACCOUNT(entity);
1421 if (gnc_account_get_book (account) != model->book)
1423 LEAVE(
"not in this book");
1428 LEAVE(
"not in this model");
1440 DEBUG(
"can't generate path");
1443 increment_stamp (model);
1444 if (!gnc_tree_model_account_get_iter (GTK_TREE_MODEL(model), &iter, path))
1446 DEBUG(
"can't generate iter");
1449 gtk_tree_model_row_inserted (GTK_TREE_MODEL(model), path, &iter);
1450 propagate_change (GTK_TREE_MODEL(model), path, 1);
1453 case QOF_EVENT_REMOVE:
1456 parent = ed->node ? GNC_ACCOUNT(ed->node) : model->root;
1458 DEBUG(
"remove child %d of account %p (%s)", ed->idx, parent, parent_name);
1462 DEBUG(
"can't generate path");
1465 increment_stamp (model);
1466 gtk_tree_path_append_index (path, ed->idx);
1467 gtk_tree_model_row_deleted (GTK_TREE_MODEL(model), path);
1468 propagate_change (GTK_TREE_MODEL(model), path, 0);
1471 case QOF_EVENT_MODIFY:
1474 gnc_tree_model_account_clear_cached_values(model, account);
1479 DEBUG(
"can't generate path");
1482 if (!gnc_tree_model_account_get_iter (GTK_TREE_MODEL(model), &iter, path))
1484 DEBUG(
"can't generate iter");
1487 gtk_tree_model_row_changed (GTK_TREE_MODEL(model), path, &iter);
1488 propagate_change (GTK_TREE_MODEL(model), path, -1);
1492 gnc_tree_model_account_clear_cached_values(model, account);
1494 LEAVE(
"unknown event type");
1499 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.