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> 56 #include "gnc-hooks.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" 69 using UniStr = icu::UnicodeString;
71 static QofLogModule log_module = GNC_MOD_GUI;
73 static bool auto_decimal_enabled =
false;
74 static int auto_decimal_places = 2;
76 static bool reverse_balance_inited =
false;
82 static char* user_default_currency =
nullptr;
83 static char* user_report_currency =
nullptr;
84 constexpr
int maximum_decimals = 15;
85 constexpr int64_t pow_10[] = {1, 10, 100, 1000, 10000, 100000, 1000000,
86 10000000, 100000000, 1000000000, 10000000000,
87 100000000000, 1000000000000, 10000000000000,
88 100000000000000, 1000000000000000};
91 gnc_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);
117 gnc_configure_account_separator (
void)
120 auto separator = gnc_normalize_account_separator (
string);
122 gnc_set_account_separator(separator);
130 gnc_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");
154 gnc_reverse_balance_init (
void)
156 gnc_configure_reverse_balance ();
157 reverse_balance_inited = TRUE;
161 gnc_reverse_balance (
const Account *account)
163 if (account ==
nullptr)
170 if (!reverse_balance_inited)
171 gnc_reverse_balance_init ();
173 return reverse_type[type];
176 gboolean gnc_using_equity_type_opening_balance_account (
QofBook* book)
178 return gnc_features_check_used (book, GNC_FEATURE_EQUITY_TYPE_OPENING_BALANCE);
181 void gnc_set_use_equity_type_opening_balance_account (
QofBook* book)
187 gnc_get_default_directory (
const char* section)
194 dir = g_strdup (g_get_user_data_dir ());
196 dir = g_strdup (g_get_home_dir ());
203 gnc_set_default_directory (
const char* section,
const char* directory)
209 gnc_get_current_book (
void)
223 gnc_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" 235 gnc_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);
329 gnc_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);
372 gnc_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);
416 gnc_get_current_root_account (
void)
418 return gnc_book_get_root_account (gnc_get_current_book ());
421 gnc_commodity_table *
422 gnc_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)
470 gnc_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");
497 gnc_get_reconcile_valid_flags (
void)
511 gnc_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 };
549 equity_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");
565 gnc_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)
668 gnc_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"));
748 static gnc_commodity*
749 gnc_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);
826 gnc_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);
835 gnc_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;
864 is_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;
887 gnc_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;
921 gnc_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;
957 gnc_account_print_info (
const Account *account, gboolean use_symbol)
959 return gnc_account_print_info_helper(account, use_symbol,
965 gnc_split_amount_print_info (Split *split, gboolean use_symbol)
970 info.use_symbol = use_symbol;
978 gnc_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;
998 gnc_default_share_print_info (
void)
1001 static bool got_it =
false;
1005 info = gnc_default_print_info_helper (5);
1014 gnc_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;
1027 gnc_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;
1061 gnc_default_price_print_info (
const gnc_commodity *curr)
1063 return gnc_price_print_info (curr, FALSE);
1068 gnc_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);
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];
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]};
1140 PWARN (
"Bad numeric from rounding: %s.",
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);
1511 constexpr
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",
1525 constexpr
const char* medium_numbers[] =
1527 "Zero",
"Ten",
"Twenty",
"Thirty",
"Forty",
1528 "Fifty",
"Sixty",
"Seventy",
"Eighty",
"Ninety" 1530 constexpr
const char* big_numbers[] =
1555 static double round(
double x)
1558 return floor(x + 0.5);
1563 numeric_to_words(gnc_numeric 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());
1627 printable_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)) 1659 static inline int64_t
1660 multiplier (
int num_decimals)
1662 switch (num_decimals)
1665 return 1000000000000;
1667 return 100000000000;
1691 PERR(
"bad fraction length");
1692 g_assert_not_reached();
1700 xaccParseAmountInternal (
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;
1955 xaccParseAmountBasicInternal (
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,
2038 gnc_set_auto_decimal_enabled (gpointer settings,
char* key, gpointer user_data)
2040 auto_decimal_enabled =
2046 gnc_set_auto_decimal_places (gpointer settings,
char* key, gpointer user_data)
2048 auto_decimal_places =
2053 gnc_auto_decimal_init (
void)
2055 auto_decimal_enabled =
2057 auto_decimal_places =
2062 gnc_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);
2095 gnc_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 ());
2163 unichar_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);
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());
void xaccAccountSetType(Account *acc, GNCAccountType tip)
Set the account's type.
void xaccSplitSetValue(Split *split, gnc_numeric val)
The xaccSplitSetValue() method sets the value of this split in the transaction's commodity.
Never round at all, and signal an error if there is a fractional result in a computation.
#define xaccTransAppendSplit(t, s)
Add a split to the transaction.
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
Returns the commodity table associated with a book.
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
gboolean xaccParseAmount(const char *in_str, gboolean monetary, gnc_numeric *result, char **endstr)
Parses in_str to obtain a numeric result.
gboolean xaccParseAmountImport(const char *in_str, gboolean monetary, gnc_numeric *result, char **endstr, gboolean skip)
Similar to xaccParseAmount, but with two differences.
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
This function sets the posted date of the transaction, specified by a time64 (see ctime(3))...
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.
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...
void gnc_account_append_child(Account *new_parent, Account *child)
This function will remove from the child account any pre-existing parent relationship, and will then add the account as a child of the new parent.
const char * gnc_print_amount_with_bidi_ltr_isolate(gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
gchar * gnc_prefs_get_string(const gchar *group, const gchar *pref_name)
Get a string value from the preferences backend.
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic 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.
int xaccAccountGetCommoditySCU(const Account *acc)
Return the SCU for the account.
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value...
#define DEBUG(format, args...)
Print a debugging message.
void gnc_features_set_used(QofBook *book, const gchar *feature)
Indicate that the current book uses the given feature.
char * gnc_wrap_text_with_bidi_ltr_isolate(const char *text)
This function helps with GTK's use of 'Unicode Bidirectional Text Algorithm'.
const char * xaccPrintAmount(gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a+b.
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.
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
stop here; the following types just aren't ready for prime time
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.
Use any denominator which gives an exactly correct ratio of numerator to denominator.
gboolean gnc_prefs_set_string(const gchar *group, const gchar *pref_name, const gchar *value)
Store a string into the preferences backend.
#define PERR(format, args...)
Log a serious error.
gnc_commodity * gnc_default_report_currency(void)
Return the default currency for use in reports, as set by the user.
char * gnc_filter_text_for_bidi_marks(const char *text)
Returns the incoming text with Unicode bidi control characters removed.
gint gnc_prefs_get_int(const gchar *group, const gchar *pref_name)
Get an integer value from the preferences backend.
gboolean gnc_numeric_negative_p(gnc_numeric a)
Returns 1 if a < 0, otherwise returns 0.
#define VREC
split is void
gnc_numeric gnc_numeric_reduce(gnc_numeric n)
Return input after reducing it by Greater Common Factor (GCF) elimination.
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Set a new currency on a transaction.
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
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...
#define PWARN(format, args...)
Log a warning.
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, regardless of what the user has set for this option.
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 ...
void xaccSplitSetAmount(Split *split, gnc_numeric amt)
The xaccSplitSetAmount() method sets the amount in the account's commodity that the split should have...
QofBook * qof_session_get_book(const QofSession *session)
Returns the QofBook of this session.
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...
Account handling public routines.
gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom, gint how)
Change the denominator of a gnc_numeric value to the specified denominator under standard arguments '...
Income accounts are used to denote income.
#define YREC
The Split has been reconciled.
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.
const char * gnc_numeric_errorCode_to_string(GNCNumericErrorCode error_code)
Returns a string representation of the given GNCNumericErrorCode.
const char * gnc_get_doclink_flag_order(void)
Get a string containing document link flag order.
#define FREC
frozen into accounting period
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.
void gnc_filter_text_set_cursor_position(const char *incoming_text, const char *symbol, int *zcursor_position)
Updates cursor_position after removal of currency symbols.
gchar * gnc_list_formatter(GList *strings)
This function takes a GList of char*, and uses locale-sensitive list formatter.
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, but uses fully-qualified names using the given separator.
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_numeric gnc_numeric_abs(gnc_numeric a)
Returns a newly created gnc_numeric that is the absolute value of the given gnc_numeric value...
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
void xaccAccountSetIsOpeningBalance(Account *acc, gboolean val)
Set the "opening-balance" flag for an account.
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
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.
#define CREC
The Split has been cleared.
int xaccSPrintAmount(char *bufp, gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
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.
Split * xaccMallocSplit(QofBook *book)
Constructor.
char * gnc_filter_text_for_control_chars(const char *text)
Returns the incoming text removed of control characters.
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.
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.
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.
char * gnc_filter_text_for_currency_symbol(const char *incoming_text, const char *symbol)
Returns the incoming text removed of a currency symbol.
Truncate fractions (round toward zero)
liability (and asset) accounts indicate generic, generalized accounts that are none of the above...
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
Account * xaccSplitGetAccount(const Split *split)
Returns the account of this split, which was set through xaccAccountInsertSplit().
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity.
#define xaccAccountInsertSplit(acc, s)
The xaccAccountInsertSplit() method will insert the indicated split into the indicated account...
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
Account * xaccMallocAccount(QofBook *book)
Constructor.
const char * gnc_get_doclink_str(char link_flag)
Get a string representing the document link type.
GNCNumericErrorCode gnc_numeric_check(gnc_numeric a)
Check for error signal in value.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
const char * gnc_get_doclink_valid_flags(void)
Get a string containing documentation link valid flags.
Account * gnc_account_get_root(Account *acc)
This routine returns the root account of the account tree that the specified account belongs to...
Account * gnc_account_lookup_by_opening_balance(Account *account, gnc_commodity *commodity)
Find the opening balance account for the currency.
const char * xaccAccountGetName(const Account *acc)
Get the account's name.
Equity account is used to balance the balance sheet.
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
API for Transactions and Splits (journal entries)
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
gnc_commodity * gnc_locale_default_currency(void)
Returns the default currency of the current locale.
void xaccAccountSetName(Account *acc, const char *str)
Set the account's name.
gboolean gnc_commodity_equiv(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equivalent.
gboolean gnc_commodity_is_iso(const gnc_commodity *cm)
Checks to see if the specified commodity is an ISO 4217 recognized currency.
The Credit card account is used to denote credit (e.g.
void xaccAccountSetCommodity(Account *acc, gnc_commodity *com)
Set the account's commodity.
#define NREC
not reconciled or cleared
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.
Utility functions for file access.