29 #include <glib/gi18n.h> 33 #include "gnc-component-manager.h" 37 #include "gnc-locale-utils.h" 39 #include "window-main-summarybar.h" 40 #include "dialog-utils.h" 45 GtkWidget *totals_combo;
46 GtkListStore *datamodel;
49 gboolean combo_popped;
50 gboolean show_negative_color;
51 gchar *negative_color;
54 #define WINDOW_SUMMARYBAR_CM_CLASS "summary-bar" 56 #define GNC_PREFS_GROUP "window.pages.account-tree.summary" 57 #define GNC_PREF_GRAND_TOTAL "grand-total" 58 #define GNC_PREF_NON_CURRENCY "non-currency" 73 gnc_commodity * currency;
81 #define TOTAL_SINGLE 0 82 #define TOTAL_CURR_TOTAL 1 83 #define TOTAL_NON_CURR_TOTAL 2 84 #define TOTAL_GRAND_TOTAL 3 90 gnc_commodity *default_currency;
92 gboolean non_currency;
102 gnc_ui_get_currency_accumulator(GList **list, gnc_commodity * currency, gint total_mode)
107 for (current = g_list_first(*list); current; current = g_list_next(current))
109 found = current->data;
111 && (found->total_mode == total_mode))
118 found->currency = currency;
119 found->assets = gnc_numeric_zero ();
120 found->profits = gnc_numeric_zero ();
121 found->total_mode = total_mode;
122 *list = g_list_append (*list, found);
131 gnc_ui_accounts_recurse (
Account *parent, GList **currency_list,
134 gnc_numeric start_amount;
135 gnc_numeric start_amount_default_currency;
136 gnc_numeric end_amount;
137 gnc_numeric end_amount_default_currency;
139 gnc_commodity * account_currency;
143 GList *children, *node;
144 gboolean non_currency = FALSE;
146 if (parent == NULL)
return;
149 for (node = children; node; node = g_list_next(node))
152 QofBook *book = gnc_account_get_book (account);
154 gnc_commodity *to_curr = options.default_currency;
159 if (options.grand_total)
160 grand_total_accum = gnc_ui_get_currency_accumulator(currency_list,
167 non_curr_accum = gnc_ui_get_currency_accumulator(currency_list,
169 TOTAL_NON_CURR_TOTAL);
172 if (!non_currency || options.non_currency)
174 currency_accum = gnc_ui_get_currency_accumulator(currency_list,
179 switch (account_type)
191 end_amount_default_currency =
198 if (!non_currency || options.non_currency)
200 currency_accum->assets =
208 non_curr_accum->assets =
214 if (options.grand_total)
216 grand_total_accum->assets =
217 gnc_numeric_add (grand_total_accum->assets, end_amount_default_currency,
222 gnc_ui_accounts_recurse(account, currency_list, options);
227 start_amount_default_currency =
234 end_amount_default_currency =
241 if (!non_currency || options.non_currency)
243 currency_accum->profits =
247 currency_accum->profits =
255 non_curr_accum->profits =
256 gnc_numeric_add (non_curr_accum->profits, start_amount_default_currency,
259 non_curr_accum->profits =
265 if (options.grand_total)
267 grand_total_accum->profits =
269 start_amount_default_currency,
272 grand_total_accum->profits =
274 end_amount_default_currency,
279 gnc_ui_accounts_recurse(account, currency_list, options);
295 g_list_free(children);
303 if (mnemonic == NULL)
306 switch (currency_accum->total_mode)
308 case TOTAL_CURR_TOTAL:
309 label_str = g_strdup_printf( _(
"%s, Total:"), mnemonic );
311 case TOTAL_NON_CURR_TOTAL:
312 label_str = g_strdup_printf( _(
"%s, Non Currency Commodities Total:"), mnemonic );
314 case TOTAL_GRAND_TOTAL:
315 label_str = g_strdup_printf( _(
"%s, Grand Total:"), mnemonic );
319 label_str = g_strdup_printf( _(
"%s:"), mnemonic );
327 COLUMN_MNEMONIC_TYPE,
331 COLUMN_PROFITS_VALUE,
359 GList *currency_list;
364 root = gnc_get_current_root_account ();
366 if (options.default_currency == NULL)
371 options.grand_total =
373 options.non_currency =
375 options.start_date = gnc_accounting_period_fiscal_start();
376 options.end_date = gnc_accounting_period_fiscal_end();
378 currency_list = NULL;
381 if (options.grand_total)
383 gnc_ui_get_currency_accumulator (¤cy_list, options.default_currency,
387 gnc_ui_get_currency_accumulator (¤cy_list, options.default_currency,
390 gnc_ui_accounts_recurse(root, ¤cy_list, options);
394 char asset_amount_string[256], profit_amount_string[256];
396 g_object_ref(summary->datamodel);
397 gtk_combo_box_set_model(GTK_COMBO_BOX(summary->totals_combo), NULL);
398 gtk_list_store_clear(summary->datamodel);
399 for (current = g_list_first(currency_list); current; current = g_list_next(current))
401 gchar *total_mode_label;
402 gchar *bidi_total, *bidi_asset_amount, *bidi_profit_amount;
404 currency_accum = current->data;
407 currency_accum->assets,
408 gnc_commodity_print_info(currency_accum->currency, TRUE));
411 currency_accum->profits,
412 gnc_commodity_print_info(currency_accum->currency, TRUE));
414 gtk_list_store_append(summary->datamodel, &iter);
415 total_mode_label = get_total_mode_label (currency_accum);
419 gtk_list_store_set(summary->datamodel, &iter,
420 COLUMN_MNEMONIC_TYPE, bidi_total,
421 COLUMN_ASSETS, _(
"Net Assets:"),
422 COLUMN_ASSETS_VALUE, bidi_asset_amount,
424 COLUMN_PROFITS, _(
"Profits:"),
425 COLUMN_PROFITS_VALUE, bidi_profit_amount,
428 g_free(total_mode_label);
430 g_free(bidi_asset_amount);
431 g_free(bidi_profit_amount);
433 gtk_combo_box_set_model(GTK_COMBO_BOX(summary->totals_combo),
434 GTK_TREE_MODEL(summary->datamodel));
435 g_object_unref(summary->datamodel);
437 gtk_combo_box_set_active(GTK_COMBO_BOX(summary->totals_combo), 0);
440 g_list_free_full (currency_list, g_free);
444 get_negative_color_str (
void)
449 GtkWidget *label = gtk_label_new (
"Color");
450 GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET(label));
451 gtk_style_context_add_class (context,
"gnc-class-negative-numbers");
452 gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
453 rgba = gdk_rgba_copy (&color);
455 color_str = g_strdup_printf (
"#%02X%02X%02X",
456 (
int)(0.5 + CLAMP (rgba->red, 0., 1.) * 255.),
457 (
int)(0.5 + CLAMP (rgba->green, 0., 1.) * 255.),
458 (
int)(0.5 + CLAMP (rgba->blue, 0., 1.) * 255.));
459 gdk_rgba_free (rgba);
464 summarybar_update_color (gpointer gsettings, gchar *key, gpointer user_data)
468 summary->negative_color = get_negative_color_str();
469 summary->show_negative_color =
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_NEGATIVE_IN_RED);
471 gnc_main_window_summary_refresh (summary);
475 gnc_main_window_summary_destroy_cb(
GNCMainSummary *summary, gpointer data)
478 gnc_unregister_gui_component(summary->component_id);
481 summarybar_update_color, summary);
483 g_free (summary->negative_color);
488 summarybar_refresh_handler(GHashTable * changes, gpointer user_data)
491 gnc_main_window_summary_refresh(summary);
495 prefs_changed_cb (gpointer prefs, gchar *pref, gpointer user_data)
498 gnc_main_window_summary_refresh(summary);
502 check_string_for_markup (gchar *
string)
505 gchar *ret_string = g_strdup (
string);
507 if (g_strrstr (ret_string,
"&") != NULL)
509 strings = g_strsplit (ret_string,
"&", -1);
511 ret_string = g_strjoinv (
"&", strings);
512 g_strfreev (strings);
514 if (g_strrstr (ret_string,
"<") != NULL)
516 strings = g_strsplit (ret_string,
"<", -1);
518 ret_string = g_strjoinv (
"<", strings);
519 g_strfreev (strings);
521 if (g_strrstr (ret_string,
">") != NULL)
523 strings = g_strsplit (ret_string,
">", -1);
525 ret_string = g_strjoinv (
">", strings);
526 g_strfreev (strings);
528 if (g_strrstr (ret_string,
"\"") != NULL)
530 strings = g_strsplit (ret_string,
"\"", -1);
532 ret_string = g_strjoinv (
""", strings);
533 g_strfreev (strings);
535 if (g_strrstr (ret_string,
"'") != NULL)
537 strings = g_strsplit (ret_string,
"'", -1);
539 ret_string = g_strjoinv (
"'", strings);
540 g_strfreev (strings);
546 cdf (GtkCellLayout *cell_layout, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter,
550 gchar *type, *assets, *assets_val, *profits, *profits_val;
551 gboolean assets_neg, profits_neg;
554 viewcol = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell),
"view_column"));
556 if (summary->combo_popped)
557 g_object_set (cell,
"xalign", 0.0, NULL);
559 g_object_set (cell,
"xalign", 0.5, NULL);
561 gtk_tree_model_get (GTK_TREE_MODEL (tree_model), iter,
562 COLUMN_MNEMONIC_TYPE, &type,
563 COLUMN_ASSETS, &assets,
564 COLUMN_ASSETS_VALUE, &assets_val,
565 COLUMN_PROFITS, &profits,
566 COLUMN_PROFITS_VALUE, &profits_val,
567 COLUMN_ASSETS_NEG, &assets_neg,
568 COLUMN_PROFITS_NEG, &profits_neg, -1);
571 g_object_set (cell,
"text", type, NULL);
575 gchar *a_string, *checked_string = check_string_for_markup (assets_val);
576 if ((summary->show_negative_color == TRUE) && (assets_neg == TRUE))
577 a_string = g_strconcat (assets,
" <span foreground='", summary->negative_color,
"'>", checked_string,
"</span>", NULL);
579 a_string = g_strconcat (assets,
" ", checked_string, NULL);
581 g_object_set (cell,
"markup", a_string, NULL);
583 g_free (checked_string);
588 gchar *p_string, *checked_string = check_string_for_markup (profits_val);
589 if ((summary->show_negative_color == TRUE) && (profits_neg == TRUE))
590 p_string = g_strconcat (profits,
" <span foreground='", summary->negative_color,
"'>", checked_string,
"</span>", NULL);
592 p_string = g_strconcat (profits,
" ", checked_string, NULL);
594 g_object_set (cell,
"markup", p_string, NULL);
596 g_free (checked_string);
603 g_free (profits_val);
607 summary_combo_popped (GObject *widget, GParamSpec *pspec, gpointer user_data)
610 if (summary->combo_popped)
611 summary->combo_popped = FALSE;
613 summary->combo_popped = TRUE;
617 gnc_main_window_summary_new (
void)
620 GtkCellRenderer *textRenderer;
623 retval->datamodel = gtk_list_store_new (N_COLUMNS,
632 retval->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
633 gtk_box_set_homogeneous (GTK_BOX (retval->hbox), FALSE);
636 gtk_widget_set_name (GTK_WIDGET(retval->hbox),
"gnc-id-account-summary-bar");
638 retval->totals_combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (retval->datamodel));
639 g_object_unref (retval->datamodel);
641 retval->negative_color = get_negative_color_str();
642 retval->show_negative_color =
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_NEGATIVE_IN_RED);
644 summarybar_update_color, retval);
646 retval->component_id = gnc_register_gui_component (WINDOW_SUMMARYBAR_CM_CLASS,
647 summarybar_refresh_handler,
649 gnc_gui_component_watch_entity_type (retval->component_id,
652 | GNC_EVENT_ITEM_CHANGED);
655 g_signal_connect (retval->totals_combo,
"notify::popup-shown",G_CALLBACK (summary_combo_popped), retval);
657 retval->combo_popped = FALSE;
659 for (i = 0; i <= N_COLUMNS - 2; i += 2)
661 textRenderer = GTK_CELL_RENDERER(gtk_cell_renderer_text_new());
663 gtk_cell_renderer_set_fixed_size (textRenderer, 50, -1);
665 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(retval->totals_combo), textRenderer, TRUE);
667 g_object_set_data (G_OBJECT(textRenderer),
"view_column", GINT_TO_POINTER (i));
668 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT(retval->totals_combo), textRenderer, cdf, retval, NULL);
671 gtk_container_set_border_width (GTK_CONTAINER (retval->hbox), 2);
672 gtk_box_pack_start (GTK_BOX(retval->hbox), retval->totals_combo, TRUE, TRUE, 5);
673 gtk_widget_show (retval->totals_combo);
674 gtk_widget_show (retval->hbox);
676 g_signal_connect_swapped (G_OBJECT (retval->hbox),
"destroy",
677 G_CALLBACK (gnc_main_window_summary_destroy_cb),
680 gnc_main_window_summary_refresh(retval);
683 prefs_changed_cb, retval);
gboolean gnc_commodity_is_currency(const gnc_commodity *cm)
Checks to see if the specified commodity is an ISO 4217 recognized currency or a legacy currency...
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
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.
utility functions for the GnuCash UI
Expense accounts are used to denote expenses.
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account's account type.
Mutual Fund accounts will typically be shown in registers which show three columns: price...
char * gnc_wrap_text_with_bidi_ltr_isolate(const char *text)
This function helps with GTK's use of 'Unicode Bidirectional Text Algorithm'.
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a+b.
The cash account type is used to denote a shoe-box or pillowcase stuffed with * cash.
GNCPriceDB * gnc_pricedb_get_db(QofBook *book)
Return the pricedb associated with the book.
gboolean gnc_numeric_negative_p(gnc_numeric a)
Returns 1 if a < 0, otherwise returns 0.
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
Account used to record multiple commodity transactions.
void gnc_prefs_remove_cb_by_id(const gchar *group, guint id)
Remove a function that was registered for a callback when a specific preference in the settings group...
Stock accounts will typically be shown in registers which show three columns: price, number of shares, and value.
Account handling public routines.
Income accounts are used to denote income.
General utilities for dealing with accounting periods.
The bank account type denotes a savings or checking account held at a bank.
const char * gnc_commodity_get_nice_symbol(const gnc_commodity *cm)
Retrieve a symbol for the specified commodity, suitable for display to the user.
Additional event handling code.
asset (and liability) accounts indicate generic, generalized accounts that are none of the above...
gnc_numeric xaccAccountGetBalanceAsOfDate(Account *acc, time64 date)
Get the balance of the account at the end of the day before the date specified.
int xaccSPrintAmount(char *bufp, gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
The currency account type indicates that the account is a currency trading account.
GNCAccountType
The account types are used to determine how the transaction data in the account is displayed...
Generic api to store and retrieve preferences.
gnc_numeric gnc_numeric_sub(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a-b.
liability (and asset) accounts indicate generic, generalized accounts that are none of the above...
GList * gnc_account_get_children(const Account *account)
This routine returns a GList of all children accounts of the specified account.
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
gnc_numeric gnc_pricedb_convert_balance_nearest_price_t64(GNCPriceDB *pdb, gnc_numeric balance, const gnc_commodity *balance_currency, const gnc_commodity *new_currency, time64 t)
Convert a balance from one currency to another using the price nearest to the given time...
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Equity account is used to balance the balance sheet.
gboolean gnc_commodity_equiv(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equivalent.
The Credit card account is used to denote credit (e.g.
An accumulator for a given currency.
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.