26#define __USE_MINGW_ANSI_STDIO 1
30#include <glib/gi18n.h>
37#if defined(G_OS_WIN32) && !defined(_MSC_VER)
45#include <unicode/uchar.h>
46#include <unicode/utf8.h>
47#include <unicode/listformatter.h>
57#include "gnc-session.h"
58#include "engine-helpers.h"
59#include "gnc-locale-utils.h"
61#define GNC_PREF_CURRENCY_CHOICE_LOCALE "currency-choice-locale"
62#define GNC_PREF_CURRENCY_CHOICE_OTHER "currency-choice-other"
63#define GNC_PREF_CURRENCY_OTHER "currency-other"
64#define GNC_PREF_REVERSED_ACCTS_NONE "reversed-accounts-none"
65#define GNC_PREF_REVERSED_ACCTS_CREDIT "reversed-accounts-credit"
66#define GNC_PREF_REVERSED_ACCTS_INC_EXP "reversed-accounts-incomeexpense"
67#define GNC_PREF_PRICES_FORCE_DECIMAL "force-price-decimal"
69using UniStr = icu::UnicodeString;
71static QofLogModule log_module = GNC_MOD_GUI;
73static bool auto_decimal_enabled =
false;
74static int auto_decimal_places = 2;
76static bool reverse_balance_inited =
false;
82static char* user_default_currency =
nullptr;
83static char* user_report_currency =
nullptr;
84constexpr int maximum_decimals = 15;
85constexpr int64_t pow_10[] = {1, 10, 100, 1000, 10000, 100000, 1000000,
86 10000000, 100000000, 1000000000, 10000000000,
87 100000000000, 1000000000000, 10000000000000,
88 100000000000000, 1000000000000000};
91gnc_normalize_account_separator (
const gchar* separator)
93 char* new_sep=
nullptr;
95 if (!separator || !*separator || g_strcmp0(separator,
"colon") == 0)
96 new_sep = g_strdup (
":");
97 else if (g_strcmp0(separator,
"slash") == 0)
98 new_sep = g_strdup (
"/");
99 else if (g_strcmp0(separator,
"backslash") == 0)
100 new_sep = g_strdup (
"\\");
101 else if (g_strcmp0(separator,
"dash") == 0)
102 new_sep = g_strdup (
"-");
103 else if (g_strcmp0(separator,
"period") == 0)
104 new_sep = g_strdup (
".");
106 new_sep = g_strdup (separator);
117gnc_configure_account_separator (
void)
120 auto separator = gnc_normalize_account_separator (
string);
122 gnc_set_account_separator(separator);
130gnc_configure_reverse_balance (
void)
133 reverse_type[i] =
false;
140 else if (
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_REVERSED_ACCTS_CREDIT))
149 PWARN(
"no reversed account preference set, using none");
154gnc_reverse_balance_init (
void)
156 gnc_configure_reverse_balance ();
157 reverse_balance_inited = TRUE;
161gnc_reverse_balance (
const Account *account)
163 if (account ==
nullptr)
170 if (!reverse_balance_inited)
171 gnc_reverse_balance_init ();
173 return reverse_type[type];
176gboolean gnc_using_equity_type_opening_balance_account (
QofBook* book)
178 return gnc_features_check_used (book, GNC_FEATURE_EQUITY_TYPE_OPENING_BALANCE);
181void gnc_set_use_equity_type_opening_balance_account (
QofBook* book)
187gnc_get_default_directory (
const char* section)
194 dir = g_strdup (g_get_user_data_dir ());
196 dir = g_strdup (g_get_home_dir ());
203gnc_set_default_directory (
const char* section,
const char* directory)
209gnc_get_current_book (
void)
223gnc_is_new_book (
void)
225 return (!gnc_current_session_exist() ||
229#define OPTION_TAXUS_NAME "tax_US/name"
230#define OPTION_TAXUS_TYPE "tax_US/type"
231#define OLD_OPTION_TAXUS_NAME "book/tax_US/name"
232#define OLD_OPTION_TAXUS_TYPE "book/tax_US/type"
235gnc_set_current_book_tax_name_type (gboolean name_changed,
const char* tax_name,
236 gboolean type_changed,
const char* tax_type)
242 auto book = gnc_get_current_book();
243 if ((g_strcmp0 (tax_name,
"") == 0) ||
244 (tax_name ==
nullptr))
246 if ((g_strcmp0 (tax_type,
"Other") == 0) ||
247 (g_strcmp0 (tax_type,
"") == 0) ||
248 (tax_type ==
nullptr))
250 qof_book_set_string_option(book, OPTION_TAXUS_NAME,
nullptr);
251 qof_book_set_string_option(book, OPTION_TAXUS_TYPE,
nullptr);
252 qof_book_option_frame_delete(book,
"tax_US");
256 qof_book_set_string_option(book, OPTION_TAXUS_NAME,
nullptr);
257 qof_book_set_string_option(book, OPTION_TAXUS_TYPE, tax_type);
262 if ((g_strcmp0 (tax_type,
"Other") == 0) ||
263 (g_strcmp0 (tax_type,
"") == 0) ||
264 (tax_type ==
nullptr))
266 qof_book_set_string_option(book, OPTION_TAXUS_TYPE,
nullptr);
267 qof_book_set_string_option(book, OPTION_TAXUS_NAME, tax_name);
271 qof_book_set_string_option(book, OPTION_TAXUS_NAME, tax_name);
272 qof_book_set_string_option(book, OPTION_TAXUS_TYPE, tax_type);
278 auto book = gnc_get_current_book();
279 if ((g_strcmp0 (tax_name,
"") == 0) ||
280 (tax_name ==
nullptr))
282 if ((g_strcmp0 (tax_type,
"Other") == 0) ||
283 (g_strcmp0 (tax_type,
"") == 0) ||
284 (tax_type ==
nullptr))
286 qof_book_set_string_option(book, OPTION_TAXUS_NAME,
nullptr);
287 qof_book_option_frame_delete(book,
"tax_US");
291 qof_book_set_string_option(book, OPTION_TAXUS_NAME,
nullptr);
296 qof_book_set_string_option(book, OPTION_TAXUS_NAME, tax_name);
304 auto book = gnc_get_current_book();
305 if ((g_strcmp0 (tax_type,
"Other") == 0) ||
306 (g_strcmp0 (tax_type,
"") == 0) ||
307 (tax_type ==
nullptr))
309 if ((g_strcmp0 (tax_name,
"") == 0) ||
310 (tax_name ==
nullptr))
312 qof_book_set_string_option(book, OPTION_TAXUS_TYPE,
nullptr);
313 qof_book_option_frame_delete(book,
"tax_US");
317 qof_book_set_string_option(book, OPTION_TAXUS_TYPE,
nullptr);
322 qof_book_set_string_option(book, OPTION_TAXUS_TYPE, tax_type);
329gnc_get_current_book_tax_name (
void)
331 auto book = gnc_get_current_book();
332 auto tax_name = qof_book_get_string_option(book, OPTION_TAXUS_NAME);
339 const char* old_option_taxus_name =
340 qof_book_get_string_option(book, OLD_OPTION_TAXUS_NAME);
341 if (old_option_taxus_name)
343 char* taxus_name = g_strdup(old_option_taxus_name);
344 const char* old_option_taxus_type =
345 qof_book_get_string_option(book, OLD_OPTION_TAXUS_TYPE);
346 if (old_option_taxus_type)
348 char* taxus_type = g_strdup(old_option_taxus_type);
349 qof_book_set_string_option(book, OPTION_TAXUS_NAME, taxus_name);
350 qof_book_set_string_option(book, OLD_OPTION_TAXUS_NAME,
nullptr);
351 qof_book_set_string_option(book, OPTION_TAXUS_TYPE, taxus_type);
352 qof_book_set_string_option(book, OLD_OPTION_TAXUS_TYPE,
nullptr);
353 qof_book_option_frame_delete(book,
"book/tax_US");
354 qof_book_option_frame_delete(book,
"book");
359 qof_book_set_string_option(book, OPTION_TAXUS_NAME, taxus_name);
360 qof_book_set_string_option(book, OLD_OPTION_TAXUS_NAME,
nullptr);
361 qof_book_option_frame_delete(book,
"book/tax_US");
362 qof_book_option_frame_delete(book,
"book");
365 return qof_book_get_string_option(book, OPTION_TAXUS_NAME);
372gnc_get_current_book_tax_type (
void)
374 auto book = gnc_get_current_book();
376 qof_book_get_string_option(book, OPTION_TAXUS_TYPE);
383 auto old_option_taxus_type =
384 qof_book_get_string_option(book, OLD_OPTION_TAXUS_TYPE);
385 if (old_option_taxus_type)
387 auto taxus_type = g_strdup(old_option_taxus_type);
388 auto old_option_taxus_name =
389 qof_book_get_string_option(book, OLD_OPTION_TAXUS_NAME);
390 if (old_option_taxus_name)
392 auto taxus_name = g_strdup(old_option_taxus_name);
393 qof_book_set_string_option(book, OPTION_TAXUS_NAME, taxus_name);
394 qof_book_set_string_option(book, OLD_OPTION_TAXUS_NAME,
nullptr);
395 qof_book_set_string_option(book, OPTION_TAXUS_TYPE, taxus_type);
396 qof_book_set_string_option(book, OLD_OPTION_TAXUS_TYPE,
nullptr);
397 qof_book_option_frame_delete(book,
"book/tax_US");
398 qof_book_option_frame_delete(book,
"book");
403 qof_book_set_string_option(book, OPTION_TAXUS_TYPE, taxus_type);
404 qof_book_set_string_option(book, OLD_OPTION_TAXUS_TYPE,
nullptr);
405 qof_book_option_frame_delete(book,
"book/tax_US");
406 qof_book_option_frame_delete(book,
"book");
409 return qof_book_get_string_option(book, OPTION_TAXUS_TYPE);
416gnc_get_current_root_account (
void)
418 return gnc_book_get_root_account (gnc_get_current_book ());
422gnc_get_current_commodities (
void)
424 if (gnc_current_session_exist())
431 gboolean show_leaf_accounts)
433 if (show_leaf_accounts)
442 auto show_leaf_accounts =
444 GNC_PREF_SHOW_LEAF_ACCT_NAMES);
452 auto show_leaf_accounts =
454 GNC_PREF_SHOW_LEAF_ACCT_NAMES);
456 if (show_leaf_accounts)
470gnc_get_reconcile_str (
char reconciled_flag)
472 switch (reconciled_flag)
475 return C_(
"Reconciled flag 'not cleared'",
"n");
477 return C_(
"Reconciled flag 'cleared'",
"c");
479 return C_(
"Reconciled flag 'reconciled'",
"y");
481 return C_(
"Reconciled flag 'frozen'",
"f");
483 return C_(
"Reconciled flag 'void'",
"v");
485 PERR(
"Bad reconciled flag\n");
497gnc_get_reconcile_valid_flags (
void)
511gnc_get_reconcile_flag_order (
void)
513 static const char flags[] = {
NREC,
CREC, 0 };
523 return C_(
"Document Link flag for 'web'",
"w");
525 return C_(
"Document Link flag for 'file'",
"f");
529 PERR(
"Bad link flag");
537 static const char flags[] = { FLINK, WLINK,
' ', 0 };
544 static const char flags[] = { FLINK, WLINK,
' ', 0 };
549equity_base_name (GNCEquityType equity_type)
553 case EQUITY_OPENING_BALANCE:
554 return N_(
"Opening Balances");
556 case EQUITY_RETAINED_EARNINGS:
557 return N_(
"Retained Earnings");
565gnc_find_or_create_equity_account (
Account *root,
566 GNCEquityType equity_type,
567 gnc_commodity *currency)
569 g_return_val_if_fail (equity_type >= 0,
nullptr);
570 g_return_val_if_fail (equity_type < NUM_EQUITY_TYPES,
nullptr);
571 g_return_val_if_fail (currency !=
nullptr,
nullptr);
572 g_return_val_if_fail (root !=
nullptr,
nullptr);
575 auto use_eq_op_feature = equity_type == EQUITY_OPENING_BALANCE && gnc_using_equity_type_opening_balance_account (gnc_get_current_book ());
577 if (use_eq_op_feature)
584 auto base_name = equity_base_name (equity_type);
592 base_name = base_name && *base_name ?
_(base_name) :
"";
599 auto base_name_exists = (account !=
nullptr);
604 if (use_eq_op_feature)
609 auto name = g_strconcat (base_name,
" - ",
615 auto name_exists = (account !=
nullptr);
620 if (use_eq_op_feature)
626 if (name_exists && base_name_exists)
628 PWARN (
"equity account with unexpected currency");
633 if (!base_name_exists &&
637 name = g_strdup (base_name);
653 if (use_eq_op_feature)
668gnc_account_create_opening_balance (
Account *account,
676 g_return_val_if_fail (account !=
nullptr, FALSE);
680 auto equity_account =
682 EQUITY_OPENING_BALANCE,
727 auto table = gnc_get_current_commodities ();
728 auto code = gnc_locale_default_iso_currency_code ();
730 auto currency = gnc_commodity_table_lookup (
table,
731 GNC_COMMODITY_NS_CURRENCY,
734 return (currency ? currency :
nullptr);
742 return (currency ? currency :
743 gnc_commodity_table_lookup (gnc_get_current_commodities (),
744 GNC_COMMODITY_NS_CURRENCY,
"USD"));
749gnc_default_currency_common (
char* requested_currency,
752 gnc_commodity *currency =
nullptr;
754 if (requested_currency)
755 return gnc_commodity_table_lookup(gnc_get_current_commodities(),
756 GNC_COMMODITY_NS_CURRENCY,
759 if (gnc_current_session_exist() &&
763 currency = gnc_commodity_table_lookup(gnc_get_current_commodities(),
764 GNC_COMMODITY_NS_CURRENCY,
766 DEBUG(
"mnemonic %s, result %p",
767 mnemonic && *mnemonic ? mnemonic :
"(null)", currency);
776 g_free (requested_currency);
785 return gnc_default_currency_common (user_default_currency,
786 GNC_PREFS_GROUP_GENERAL);
791 gboolean * currency_from_account_found)
793 gnc_commodity *currency;
796 if (currency_from_account_found)
797 *currency_from_account_found = FALSE;
804 if (currency_from_account_found)
805 *currency_from_account_found = TRUE;
809 if (currency_from_account_found)
810 *currency_from_account_found = FALSE;
821 return gnc_default_currency_common (user_report_currency,
822 GNC_PREFS_GROUP_GENERAL_REPORT);
826gnc_currency_changed_cb (GSettings *settings,
char* key, gpointer user_data)
828 user_default_currency =
nullptr;
829 user_report_currency =
nullptr;
830 gnc_hook_run(HOOK_CURRENCY_CHANGED,
nullptr);
835gnc_default_print_info (gboolean use_symbol)
838 static bool got_it =
false;
841 info.use_symbol = use_symbol ? 1 : 0;
847 auto lc = gnc_localeconv ();
849 info.max_decimal_places = lc->frac_digits;
850 info.min_decimal_places = lc->frac_digits;
852 info.use_separators = 1;
864is_decimal_fraction (int64_t fraction, uint8_t *max_decimal_places_p)
866 uint8_t max_decimal_places = 0;
871 while (fraction != 1)
873 if (fraction % 10 != 0)
876 fraction = fraction / 10;
877 max_decimal_places += 1;
880 if (max_decimal_places_p)
881 *max_decimal_places_p = max_decimal_places;
887gnc_commodity_print_info (
const gnc_commodity *commodity,
892 if (commodity ==
nullptr)
893 return gnc_default_print_info (use_symbol);
895 info.commodity = commodity;
900 &info.max_decimal_places))
903 info.min_decimal_places = info.max_decimal_places;
905 info.min_decimal_places = 0;
908 info.max_decimal_places = info.min_decimal_places = 0;
910 info.use_separators = 1;
911 info.use_symbol = use_symbol ? 1 : 0;
912 info.use_locale = is_iso ? 1 : 0;
921gnc_account_print_info_helper(
const Account *account, gboolean use_symbol,
922 gnc_commodity * (*efffunc)(
const Account *),
923 int (*scufunc)(
const Account*))
927 if (account ==
nullptr)
928 return gnc_default_print_info (use_symbol);
930 info.commodity = efffunc (account);
934 auto scu = scufunc (account);
936 if (is_decimal_fraction (scu, &info.max_decimal_places))
939 info.min_decimal_places = info.max_decimal_places;
941 info.min_decimal_places = 0;
944 info.max_decimal_places = info.min_decimal_places = 0;
946 info.use_separators = 1;
947 info.use_symbol = use_symbol ? 1 : 0;
948 info.use_locale = is_iso ? 1 : 0;
957gnc_account_print_info (
const Account *account, gboolean use_symbol)
959 return gnc_account_print_info_helper(account, use_symbol,
965gnc_split_amount_print_info (Split *split, gboolean use_symbol)
970 info.use_symbol = use_symbol;
978gnc_default_print_info_helper (
int decplaces)
982 info.commodity =
nullptr;
984 info.max_decimal_places = decplaces;
985 info.min_decimal_places = 0;
987 info.use_separators = 1;
998gnc_default_share_print_info (
void)
1001 static bool got_it =
false;
1005 info = gnc_default_print_info_helper (5);
1014gnc_share_print_info_places (
int decplaces)
1018 info = gnc_default_share_print_info ();
1019 info.max_decimal_places = decplaces;
1020 info.min_decimal_places = decplaces;
1027gnc_price_print_info (
const gnc_commodity *curr, gboolean use_symbol)
1031 GNC_PREF_PRICES_FORCE_DECIMAL);
1032 info.commodity = curr;
1037 guint8 decplaces = 0;
1038 while (frac != 1 && (frac % 10) == 0 && (frac /= 10)) ++decplaces;
1041 info.max_decimal_places = decplaces;
1042 info.min_decimal_places = decplaces;
1046 info.max_decimal_places = 6;
1047 info.min_decimal_places = 0;
1050 info.use_separators = 1;
1051 info.use_symbol = use_symbol ? 1 : 0;
1052 info.use_locale = 1;
1055 info.force_fit = force;
1061gnc_default_price_print_info (
const gnc_commodity *curr)
1063 return gnc_price_print_info (curr, FALSE);
1068gnc_integral_print_info (
void)
1071 static bool got_it =
false;
1075 info = gnc_default_print_info_helper (0);
1086 auto *lc = gnc_localeconv();
1087 constexpr size_t buf_size = 128;
1088 char temp_buf[buf_size];
1090 g_return_val_if_fail (info !=
nullptr, 0);
1092 if (gnc_numeric_check (val))
1094 PWARN (
"Bad numeric: %s.",
1106 if (!value_is_decimal && info->force_fit && info->round)
1113 const int64_t denom = info->commodity ?
1115 (info->max_decimal_places &&
1116 info->max_decimal_places <= maximum_decimals) ?
1117 pow_10[info->max_decimal_places] : pow_10[maximum_decimals];
1118 val = gnc_numeric_convert(val, denom, GNC_HOW_RND_ROUND_HALF_UP);
1121 auto min_dp = info->min_decimal_places;
1122 auto max_dp = info->max_decimal_places;
1126 if (!info->force_fit)
1130 if (value_is_decimal && info->round && info->force_fit)
1133 gnc_numeric rounding{5, pow_10[max_dp + 1]};
1136 GNC_HOW_DENOM_EXACT | GNC_HOW_RND_TRUNC);
1140 PWARN (
"Bad numeric from rounding: %s.",
1148 auto whole = gnc_numeric_convert(val, 1, GNC_HOW_RND_TRUNC);
1150 if (gnc_numeric_check (val))
1152 PWARN (
"Problem with remainder: %s.",
1161 snprintf(temp_buf, buf_size,
"%" G_GINT64_FORMAT, whole.num);
1162 auto num_whole_digits = strlen (temp_buf);
1164 if (!info->use_separators)
1165 strcpy (buf, temp_buf);
1173 separator = lc->mon_thousands_sep;
1174 group = lc->mon_grouping;
1178 separator = lc->thousands_sep;
1179 group = lc->grouping;
1183 auto temp_ptr = &temp_buf[num_whole_digits - 1];
1184 auto group_count = 0;
1186 while (temp_ptr != temp_buf)
1188 *buf_ptr++ = *temp_ptr--;
1190 if (*group != CHAR_MAX)
1194 if (group_count == *group)
1196 g_utf8_strncpy(buf_ptr, separator, 1);
1197 buf_ptr = g_utf8_find_next_char(buf_ptr,
nullptr);
1219 *buf_ptr++ = *temp_ptr;
1221 auto rev_buf = g_utf8_strreverse(buf, -1);
1222 strcpy (buf, rev_buf);
1229 if (!value_is_decimal)
1234 snprintf (temp_buf, buf_size,
"%" G_GINT64_FORMAT
"/%" G_GINT64_FORMAT,
1235 val.num, val.denom);
1237 snprintf (temp_buf, buf_size,
"%" G_GINT64_FORMAT
" * %" G_GINT64_FORMAT,
1238 val.num, -val.denom);
1242 else if (value_is_negative)
1247 strcat (buf, temp_buf);
1251 guint8 num_decimal_places = 0;
1252 char* temp_ptr = temp_buf;
1254 auto decimal_point = info->monetary
1255 ? lc->mon_decimal_point
1256 : lc->decimal_point;
1257 g_utf8_strncpy(temp_ptr, decimal_point, 1);
1258 temp_ptr = g_utf8_find_next_char(temp_ptr,
nullptr);
1262 && (num_decimal_places < max_dp))
1266 val.denom = val.denom / 10;
1268 digit = val.num / val.denom;
1270 *temp_ptr++ = digit +
'0';
1271 num_decimal_places++;
1273 val.num = val.num - (digit * val.denom);
1276 while (num_decimal_places < min_dp)
1279 num_decimal_places++;
1286 while (*temp_ptr ==
'0' && num_decimal_places > min_dp)
1289 num_decimal_places--;
1292 if (num_decimal_places > max_dp)
1294 PWARN (
"max_decimal_places too small; limit %d, value %s%s",
1295 info->max_decimal_places, buf, temp_buf);
1298 strcat (buf, temp_buf);
1310 auto orig_bufp = bufp;
1311 auto currency_symbol =
"";
1318 bool print_sign =
true;
1319 bool print_absolute =
false;
1324 auto lc = gnc_localeconv();
1325 if (info.use_locale)
1328 cs_precedes = lc->n_cs_precedes;
1329 sep_by_space = lc->n_sep_by_space;
1333 cs_precedes = lc->p_cs_precedes;
1334 sep_by_space = lc->p_sep_by_space;
1339 sep_by_space = TRUE;
1342 if (info.commodity && info.use_symbol)
1347 cs_precedes = FALSE;
1348 sep_by_space = TRUE;
1354 sign = lc->negative_sign;
1355 sign_posn = lc->n_sign_posn;
1359 sign = lc->positive_sign;
1360 sign_posn = lc->p_sign_posn;
1367 if (print_sign && (sign_posn == 1))
1368 bufp = g_stpcpy(bufp, sign);
1374 if (print_sign && (sign_posn == 3))
1375 bufp = g_stpcpy(bufp, sign);
1377 if (info.use_symbol)
1379 bufp = g_stpcpy(bufp, currency_symbol);
1381 bufp = g_stpcpy(bufp,
" ");
1385 if (print_sign && (sign_posn == 4))
1386 bufp = g_stpcpy(bufp, sign);
1390 if (print_sign && (sign_posn == 0))
1392 bufp = g_stpcpy(bufp,
"(");
1393 print_absolute = TRUE;
1397 bufp += PrintAmountInternal(bufp,
1402 if (print_sign && (sign_posn == 0))
1403 bufp = g_stpcpy(bufp,
")");
1409 if (print_sign && (sign_posn == 3))
1410 bufp = g_stpcpy(bufp, sign);
1412 if (info.use_symbol)
1415 bufp = g_stpcpy(bufp,
" ");
1416 bufp = g_stpcpy(bufp, currency_symbol);
1420 if (print_sign && (sign_posn == 4))
1421 bufp = g_stpcpy(bufp, sign);
1425 if (print_sign && (sign_posn == 2))
1426 bufp = g_stpcpy(bufp, sign);
1429 return (bufp - orig_bufp);
1438 static char buf[BUFLEN];
1451 static char buf[BUFLEN];
1452 static const char ltr_isolate[] = {
'\xe2',
'\x81',
'\xa6' };
1453 static const char ltr_pop_isolate[] = {
'\xe2',
'\x81',
'\xa9' };
1454 auto offset = info.use_symbol ? 3 : 0;
1459 memset (buf, 0, BUFLEN);
1469 memcpy (buf, ltr_isolate, 3);
1471 if (buf[BUFLEN - 4] ==
'\0')
1473 auto length = strlen (buf);
1474 memcpy (buf + length, ltr_pop_isolate, 3);
1478 buf[BUFLEN - 1] =
'\0';
1479 memcpy (buf + BUFLEN - 4, ltr_pop_isolate, 3);
1481 PWARN(
"buffer length %d exceeded, string truncated was %s", BUFLEN, buf);
1491 static const char* ltr =
"\u2066";
1492 static const char* pop =
"\u2069";
1497 return g_strconcat (ltr, text, pop,
nullptr);
1511constexpr const char* small_numbers[] =
1519 "Zero",
"One",
"Two",
"Three",
"Four",
1520 "Five",
"Six",
"Seven",
"Eight",
"Nine",
1521 "Ten",
"Eleven",
"Twelve",
"Thirteen",
"Fourteen",
1522 "Fifteen",
"Sixteen",
"Seventeen",
"Eighteen",
"Nineteen",
1525constexpr const char* medium_numbers[] =
1527 "Zero",
"Ten",
"Twenty",
"Thirty",
"Forty",
1528 "Fifty",
"Sixty",
"Seventy",
"Eighty",
"Ninety"
1530constexpr const char* big_numbers[] =
1555static double round(
double x)
1558 return floor(x + 0.5);
1563numeric_to_words(gnc_numeric val)
1566 val = gnc_numeric_convert (val, 1, GNC_HOW_RND_NEVER);
1567 if (gnc_numeric_check (val))
1568 return g_strdup (
"");
1572 auto append_word = [&out](
auto word){
if (!out.empty()) out +=
' '; out += word; };
1573 auto append_below_1000 = [&](uint64_t n)
1577 append_word (small_numbers[n / 100]);
1578 append_word (big_numbers[0]);
1583 append_word (medium_numbers[n / 10]);
1587 append_word (small_numbers[n]);
1590 auto absnum = val.num < 0 ? 0 -
static_cast<uint64_t
> (val.num)
1591 : static_cast<uint64_t> (val.num);
1592 auto denom =
static_cast<uint64_t
> (val.denom);
1593 auto whole = absnum / denom;
1598 std::vector<unsigned> groups;
1599 for (; whole; whole /= 1000)
1600 groups.push_back (whole % 1000);
1602 for (
int i = groups.size() - 1; i >= 0; --i)
1606 append_below_1000 (groups[i]);
1608 append_word (big_numbers[i]);
1615 auto rem = absnum % denom;
1616 for (
auto d = denom, r = rem ? rem : 1; d % 10 == 0; d /= 10, r /= 10)
1619 out += std::to_string (rem);
1621 out += std::to_string (denom);
1623 return g_strndup (out.c_str(), out.size());
1627printable_value (
double val,
int denom)
1629 auto num = gnc_numeric_create(round(val * denom), denom);
1630 auto info = gnc_share_print_info_places(log10(denom));
1657#define done_state(state) (((state) == DONE_ST) || ((state) == NO_NUM_ST))
1659static inline int64_t
1660multiplier (
int num_decimals)
1662 switch (num_decimals)
1665 return 1000000000000;
1667 return 100000000000;
1691 PERR(
"bad fraction length");
1692 g_assert_not_reached();
1700xaccParseAmountInternal (
const char* in_str, gboolean monetary,
1701 gunichar negative_sign, gunichar decimal_point,
1702 gunichar group_separator,
const char* ignore_list,
1703 gboolean use_auto_decimal,
1704 gnc_numeric *result,
char** endstr)
1708 *endstr = (
char* ) in_str;
1714 if (!g_utf8_validate(in_str, -1, &in))
1716 printf(
"Invalid utf8 string '%s'. Bad character at position %ld.\n",
1717 in_str, g_utf8_pointer_to_offset (in_str, in));
1723 auto out_str = g_new(gchar, strlen(in_str) + 128);
1729 auto is_negative =
false;
1730 auto got_decimal =
false;
1731 auto need_paren =
false;
1736 auto state = START_ST;
1741 auto next_state = state;
1742 auto uc = g_utf8_get_char(in);
1745 if (ignore_list && uc && g_utf8_strchr(ignore_list, -1, uc))
1747 in = g_utf8_next_char(in);
1757 if (g_unichar_isdigit(uc))
1759 int count = g_unichar_to_utf8(uc, out);
1762 next_state = NUMER_ST;
1764 else if (uc == decimal_point)
1765 next_state = FRAC_ST;
1766 else if (g_unichar_isspace(uc))
1768 else if (uc == negative_sign)
1771 next_state = NEG_ST;
1777 next_state = NEG_ST;
1780 next_state = NO_NUM_ST;
1787 if (g_unichar_isdigit(uc))
1789 int count = g_unichar_to_utf8(uc, out);
1791 next_state = NUMER_ST;
1793 else if (uc == decimal_point)
1794 next_state = FRAC_ST;
1795 else if (g_unichar_isspace(uc))
1798 next_state = NO_NUM_ST;
1805 if (g_unichar_isdigit(uc))
1807 int count = g_unichar_to_utf8(uc, out);
1810 else if (uc == decimal_point)
1811 next_state = FRAC_ST;
1812 else if (uc == group_separator)
1814 else if (uc ==
')' && need_paren)
1816 next_state = DONE_ST;
1820 next_state = DONE_ST;
1826 if (g_unichar_isdigit(uc))
1828 int count = g_unichar_to_utf8(uc, out);
1831 else if (uc == decimal_point)
1836 if (g_unichar_isspace(decimal_point))
1837 next_state = DONE_ST;
1839 next_state = NO_NUM_ST;
1841 else if (uc == group_separator)
1846 if (g_unichar_isspace(group_separator))
1847 next_state = DONE_ST;
1849 else if (uc ==
')' && need_paren)
1851 next_state = DONE_ST;
1855 next_state = DONE_ST;
1861 g_assert_not_reached();
1867 if (((next_state == FRAC_ST) && (state != FRAC_ST)) ||
1868 ((next_state == DONE_ST) && !got_decimal))
1872 if (*out_str && sscanf(out_str,
"%" SCNd64, &numer) < 1)
1873 next_state = NO_NUM_ST;
1874 else if (next_state == FRAC_ST)
1885 if (done_state (state))
1888 in = g_utf8_next_char(in);
1892 if (need_paren || (state == NO_NUM_ST))
1902 if (got_decimal && *out_str)
1905 auto len = strlen(out_str);
1914 if (sscanf (out_str,
"%" SCNd64 , &fraction) < 1)
1920 denom = multiplier(len);
1924 else if (monetary && use_auto_decimal && !got_decimal)
1926 if ((auto_decimal_places > 0) && (auto_decimal_places <= 12))
1928 denom = multiplier(auto_decimal_places);
1940 *result = gnc_numeric_create (numer, denom);
1946 *endstr = (
char* ) in;
1955xaccParseAmountBasicInternal (
const char* in_str, gboolean monetary,
1956 gboolean use_auto_decimal, gnc_numeric *result,
1957 char** endstr, gboolean skip)
1959 struct lconv *lc = gnc_localeconv();
1960 gunichar negative_sign = g_utf8_get_char(lc->negative_sign);
1962 gunichar decimal_point;
1963 gunichar group_separator;
1966 group_separator = g_utf8_get_char(lc->mon_thousands_sep);
1967 decimal_point = g_utf8_get_char(lc->mon_decimal_point);
1971 group_separator = g_utf8_get_char(lc->thousands_sep);
1972 decimal_point = g_utf8_get_char(lc->decimal_point);
1975 const char* ignore =
nullptr;
1981 ignore = lc->positive_sign;
1982 if (!ignore || !*ignore)
1986 return xaccParseAmountInternal(in_str, monetary, negative_sign,
1987 decimal_point, group_separator,
1988 ignore, use_auto_decimal,
1997 return xaccParseAmountBasicInternal (in_str, monetary, auto_decimal_enabled,
1998 result, endstr, FALSE);
2003 gnc_numeric *result,
2004 char** endstr, gboolean skip)
2006 return xaccParseAmountBasicInternal (in_str, monetary, FALSE,
2007 result, endstr, skip);
2013 gunichar negative_sign, gunichar decimal_point,
2014 gunichar group_separator,
const char* ignore_list,
2015 gnc_numeric *result,
char** endstr)
2017 return xaccParseAmountInternal (in_str, monetary, negative_sign,
2018 decimal_point, group_separator,
2019 ignore_list, auto_decimal_enabled,
2025 gunichar negative_sign, gunichar decimal_point,
2026 gunichar group_separator,
const char* ignore_list,
2027 gnc_numeric *result,
char** endstr)
2029 return xaccParseAmountInternal (in_str, monetary, negative_sign,
2030 decimal_point, group_separator,
2038gnc_set_auto_decimal_enabled (gpointer settings,
char* key, gpointer user_data)
2040 auto_decimal_enabled =
2046gnc_set_auto_decimal_places (gpointer settings,
char* key, gpointer user_data)
2048 auto_decimal_places =
2053gnc_auto_decimal_init (
void)
2055 auto_decimal_enabled =
2057 auto_decimal_places =
2062gnc_ui_util_init (
void)
2064 gnc_configure_account_separator ();
2065 gnc_auto_decimal_init();
2068 (
void*)gnc_configure_account_separator,
nullptr);
2070 (
void*)gnc_configure_reverse_balance,
nullptr);
2072 (
void*)gnc_configure_reverse_balance,
nullptr);
2074 (
void*)gnc_configure_reverse_balance,
nullptr);
2076 (
void*)gnc_currency_changed_cb,
nullptr);
2078 (
void*)gnc_currency_changed_cb,
nullptr);
2080 (
void*)gnc_currency_changed_cb,
nullptr);
2082 (
void*)gnc_currency_changed_cb,
nullptr);
2084 (
void*)gnc_currency_changed_cb,
nullptr);
2086 (
void*)gnc_currency_changed_cb,
nullptr);
2088 (
void*)gnc_set_auto_decimal_enabled,
nullptr);
2090 (
void*)gnc_set_auto_decimal_places,
nullptr);
2095gnc_ui_util_remove_registered_prefs (
void)
2099 GNC_PREF_ACCOUNT_SEPARATOR,
2100 (
void*)gnc_configure_account_separator,
nullptr);
2102 GNC_PREF_REVERSED_ACCTS_NONE,
2103 (
void*)gnc_configure_reverse_balance,
nullptr);
2105 GNC_PREF_REVERSED_ACCTS_CREDIT,
2106 (
void*)gnc_configure_reverse_balance,
nullptr);
2108 GNC_PREF_REVERSED_ACCTS_INC_EXP,
2109 (
void*)gnc_configure_reverse_balance,
nullptr);
2111 GNC_PREF_CURRENCY_CHOICE_LOCALE,
2112 (
void*)gnc_currency_changed_cb,
nullptr);
2114 GNC_PREF_CURRENCY_CHOICE_OTHER,
2115 (
void*)gnc_currency_changed_cb,
nullptr);
2117 GNC_PREF_CURRENCY_OTHER,
2118 (
void*)gnc_currency_changed_cb,
nullptr);
2120 GNC_PREF_CURRENCY_CHOICE_LOCALE,
2121 (
void*)gnc_currency_changed_cb,
nullptr);
2123 GNC_PREF_CURRENCY_CHOICE_OTHER,
2124 (
void*)gnc_currency_changed_cb,
nullptr);
2126 GNC_PREF_CURRENCY_OTHER,
2127 (
void*)gnc_currency_changed_cb,
nullptr);
2129 GNC_PREF_AUTO_DECIMAL_POINT,
2130 (
void*)gnc_set_auto_decimal_enabled,
nullptr);
2132 GNC_PREF_AUTO_DECIMAL_PLACES,
2133 (
void*)gnc_set_auto_decimal_places,
nullptr);
2142 int32_t len =
static_cast<int32_t
> (strlen (text));
2144 result.reserve (len);
2146 const char* p = text;
2153 U8_NEXT (p, i, len, c);
2155 if (c >= 0 && !u_hasBinaryProperty (c, UCHAR_BIDI_CONTROL))
2156 result.append (p + start, i - start);
2159 return g_strdup (result.c_str ());
2163unichar_is_cntrl (gunichar uc)
2165 return (uc < 0x20 || (uc > 0x7e && uc < 0xa0));
2172 bool text_found =
false;
2177 if (!g_utf8_validate (text, -1,
nullptr))
2180 auto filtered = g_string_sized_new (strlen (text) + 1);
2186 auto uc = g_utf8_get_char (ch);
2189 if (unichar_is_cntrl (uc) && !text_found)
2191 ch = g_utf8_next_char (ch);
2195 if (!unichar_is_cntrl (uc))
2197 filtered = g_string_append_unichar (filtered, uc);
2201 if (unichar_is_cntrl (uc))
2204 ch = g_utf8_next_char (ch);
2208 auto uc2 = g_utf8_get_char (ch);
2210 if (!unichar_is_cntrl (uc2))
2211 filtered = g_string_append_unichar (filtered,
' ');
2215 return g_string_free (filtered, FALSE);
2219gnc_filter_text_set_cursor_position (
const char* incoming_text,
2221 gint *cursor_position)
2225 if (*cursor_position == 0)
2228 if (!incoming_text || !symbol)
2231 if (g_strrstr (incoming_text, symbol) ==
nullptr)
2234 auto text_len = g_utf8_strlen (incoming_text, -1);
2236 for (
int x = 0; x < text_len; x++)
2238 auto temp = g_utf8_offset_to_pointer (incoming_text, x);
2240 if (g_str_has_prefix (temp, symbol))
2243 if (g_strrstr (temp, symbol) ==
nullptr)
2246 *cursor_position = *cursor_position - (num * g_utf8_strlen (symbol, -1));
2257 return g_strdup (incoming_text);
2259 if (g_strrstr (incoming_text, symbol) ==
nullptr)
2260 return g_strdup (incoming_text);
2262 auto split = g_strsplit (incoming_text, symbol, -1);
2264 auto ret_text = g_strjoinv (
nullptr, split);
2272 const char* incoming_text,
2273 const char** symbol)
2284 return g_strdup (incoming_text);
2298 g_return_val_if_fail (strings,
nullptr);
2300 UErrorCode status = U_ZERO_ERROR;
2301 auto formatter = icu::ListFormatter::createInstance(status);
2302 std::vector<UniStr> strvec;
2306 for (
auto n = strings; n; n = g_list_next (n))
2308 auto utf8_str{
static_cast<const char*
>(n->data)};
2309 strvec.push_back (UniStr::fromUTF8(utf8_str));
2312 formatter->format (strvec.data(), strvec.size(), result, status);
2314 if (U_FAILURE(status))
2315 PERR (
"Unicode error");
2317 result.toUTF8String(retval);
2320 return g_strdup (retval.c_str());
Account handling public routines.
API for Transactions and Splits (journal entries)
All type declarations for the whole Gnucash engine.
Utility functions for file access.
Generic api to store and retrieve preferences.
utility functions for the GnuCash UI
const char * xaccAccountGetName(const Account *acc)
Get the account's name.
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
Account * gnc_account_get_root(Account *acc)
This routine returns the root account of the account tree that the specified account belongs to.
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
gchar * gnc_account_get_full_name(const Account *account)
The gnc_account_get_full_name routine returns the fully qualified name of the account using the given...
gnc_commodity * gnc_account_get_currency_or_parent(const Account *account)
Returns a gnc_commodity that is a currency, suitable for being a Transaction's currency.
void gnc_account_append_child(Account *new_parent, Account *child)
This function will remove from the child account any pre-existing parent relationship,...
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account's account type.
int xaccAccountGetCommoditySCU(const Account *acc)
Return the SCU for the account.
void xaccAccountSetName(Account *acc, const char *str)
Set the account's name.
void xaccAccountSetType(Account *acc, GNCAccountType tip)
Set the account's type.
Account * xaccMallocAccount(QofBook *book)
Constructor.
gint gnc_account_n_children(const Account *account)
Return the number of children of the specified account.
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity
void xaccAccountSetCommodity(Account *acc, gnc_commodity *com)
Set the account's commodity.
@ ACCT_TYPE_INCOME
Income accounts are used to denote income.
@ ACCT_TYPE_EXPENSE
Expense accounts are used to denote expenses.
@ ACCT_TYPE_PAYABLE
A/P account type.
@ ACCT_TYPE_LIABILITY
liability (and asset) accounts indicate generic, generalized accounts that are none of the above.
@ ACCT_TYPE_EQUITY
Equity account is used to balance the balance sheet.
@ ACCT_TYPE_CREDIT
The Credit card account is used to denote credit (e.g.
@ NUM_ACCOUNT_TYPES
stop here; the following types just aren't ready for prime time
QofBook * qof_session_get_book(const QofSession *session)
Returns the QofBook of this session.
gboolean gnc_commodity_equiv(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equivalent.
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
const char * gnc_commodity_get_nice_symbol(const gnc_commodity *cm)
Retrieve a symbol for the specified commodity, suitable for display to the user.
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
Returns the commodity table associated with a book.
gboolean gnc_commodity_is_iso(const gnc_commodity *cm)
Checks to see if the specified commodity is an ISO 4217 recognized currency.
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic for the specified commodity.
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.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
void xaccAccountSetIsOpeningBalance(Account *acc, gboolean val)
Set the "opening-balance" flag for an account.
#define xaccTransAppendSplit(t, s)
Add a split to the transaction.
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
Account * gnc_account_lookup_by_opening_balance(Account *account, gnc_commodity *commodity)
Find the opening balance account for the currency.
Account * gnc_account_lookup_by_name(const Account *parent, const char *name)
The gnc_account_lookup_by_name() subroutine fetches the account by name from the descendants of the s...
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
This function sets the posted date of the transaction, specified by a time64 (see ctime(3)).
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Set a new currency on a transaction.
#define xaccAccountInsertSplit(acc, s)
The xaccAccountInsertSplit() method will insert the indicated split into the indicated account.
Account * gnc_account_lookup_by_full_name(const Account *any_acc, const gchar *name)
The gnc_account_lookup_full_name() subroutine works like gnc_account_lookup_by_name,...
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
char * gnc_get_account_name_for_register(const Account *account)
Get either the full name of the account or the simple name, depending on the configuration parameter ...
gboolean xaccParseAmountExtended(const char *in_str, gboolean monetary, gunichar negative_sign, gunichar decimal_point, gunichar group_separator, const char *ignore_list, gnc_numeric *result, char **endstr)
Converts a string to a gnc_numeric.
int xaccSPrintAmount(char *bufp, gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
char * gnc_wrap_text_with_bidi_ltr_isolate(const char *text)
This function helps with GTK's use of 'Unicode Bidirectional Text Algorithm'.
char * gnc_filter_text_for_control_chars(const char *text)
Returns the incoming text removed of control characters.
gchar * gnc_list_formatter(GList *strings)
This function takes a GList of char*, and uses locale-sensitive list formatter.
char * gnc_filter_text_for_currency_symbol(const char *incoming_text, const char *symbol)
Returns the incoming text removed of a currency symbol.
gboolean xaccParseAmountImport(const char *in_str, gboolean monetary, gnc_numeric *result, char **endstr, gboolean skip)
Similar to xaccParseAmount, but with two differences.
Account * gnc_account_lookup_for_register(const Account *base_account, const char *name)
Retrieve the account matching the given name starting from the descendants of base_account.
const char * gnc_get_doclink_flag_order(void)
Get a string containing document link flag order.
gnc_commodity * gnc_locale_default_currency(void)
Returns the default currency of the current locale.
char * gnc_filter_text_for_currency_commodity(const gnc_commodity *comm, const char *incoming_text, const char **symbol)
Returns the incoming text removed of currency symbol.
gnc_commodity * gnc_locale_default_currency_nodefault(void)
Returns the default currency of the current locale, or NULL if no sensible currency could be identifi...
char * gnc_filter_text_for_bidi_marks(const char *text)
Returns the incoming text with Unicode bidi control characters removed.
const char * gnc_get_doclink_valid_flags(void)
Get a string containing documentation link valid flags.
const char * xaccPrintAmount(gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
char * gnc_get_account_name_for_split_register(const Account *account, gboolean show_leaf_accounts)
Get either the full name of the account or the simple name, depending on the show_leaf_accounts.
gnc_commodity * gnc_account_or_default_currency(const Account *account, gboolean *currency_from_account_found)
Returns a gnc_commodity that is a currency, suitable for being a Transaction's currency.
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
const char * gnc_print_amount_with_bidi_ltr_isolate(gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
gboolean xaccParseAmountExtImport(const char *in_str, gboolean monetary, gunichar negative_sign, gunichar decimal_point, gunichar group_separator, const char *ignore_list, gnc_numeric *result, char **endstr)
Similar to xaccParseAmountExtended, but will not automatically set a decimal point,...
gboolean xaccParseAmount(const char *in_str, gboolean monetary, gnc_numeric *result, char **endstr)
Parses in_str to obtain a numeric result.
const char * gnc_get_doclink_str(char link_flag)
Get a string representing the document link type.
gnc_commodity * gnc_default_report_currency(void)
Return the default currency for use in reports, as set by the user.
#define DEBUG(format, args...)
Print a debugging message.
#define PERR(format, args...)
Log a serious error.
#define PWARN(format, args...)
Log a warning.
const char * gnc_numeric_errorCode_to_string(GNCNumericErrorCode error_code)
Returns a string representation of the given GNCNumericErrorCode.
gboolean gnc_numeric_to_decimal(gnc_numeric *a, guint8 *max_decimal_places)
Attempt to convert the denominator to an exact power of ten without rounding.
gnc_numeric gnc_numeric_sub(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a-b.
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
GNCNumericErrorCode gnc_numeric_check(gnc_numeric in)
Check for error signal in value.
gnc_numeric gnc_numeric_abs(gnc_numeric a)
Returns a newly created gnc_numeric that is the absolute value of the given gnc_numeric value.
gboolean gnc_numeric_negative_p(gnc_numeric a)
Returns 1 if a < 0, otherwise returns 0.
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else 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.
gnc_numeric gnc_numeric_reduce(gnc_numeric in)
Return input after reducing it by Greater Common Factor (GCF) elimination.
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a+b.
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.
gint gnc_prefs_get_int(const gchar *group, const gchar *pref_name)
Get an integer value from the preferences backend.
gchar * gnc_prefs_get_string(const gchar *group, const gchar *pref_name)
Get a string value from the preferences backend.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
gboolean gnc_prefs_set_string(const gchar *group, const gchar *pref_name, const gchar *value)
Store a string into the preferences backend.
void xaccSplitSetValue(Split *split, gnc_numeric val)
The xaccSplitSetValue() method sets the value of this split in the transaction's commodity.
Split * xaccMallocSplit(QofBook *book)
Constructor.
void xaccSplitSetAmount(Split *split, gnc_numeric amt)
The xaccSplitSetAmount() method sets the amount in the account's commodity that the split should have...
#define VREC
split is void
Account * xaccSplitGetAccount(const Split *split)
Returns the account of this split, which was set through xaccAccountInsertSplit().
#define NREC
not reconciled or cleared
#define FREC
frozen into accounting period
#define CREC
The Split has been cleared
#define YREC
The Split has been reconciled.
void gnc_features_set_used(QofBook *book, const gchar *feature)
Indicate that the current book uses the given feature.