gnucash stable: Bug 799821 - £ symbol across whole UI shows as ã
John Ralls
jralls at code.gnucash.org
Tue Sep 29 18:36:27 EDT 2026
Updated via https://github.com/Gnucash/gnucash/commit/56ccad9a (commit)
from https://github.com/Gnucash/gnucash/commit/55ed9d2e (commit)
commit 56ccad9a66af75ae3cc3ded43d1aef329ca06c94
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Sep 29 15:32:35 2026 -0700
Bug 799821 - £ symbol across whole UI shows as ã
Windows: Get UTF16 localization strings and convert them thus bypassing
the code page problem entirely.
diff --git a/libgnucash/core-utils/gnc-locale-utils.c b/libgnucash/core-utils/gnc-locale-utils.c
index 966e67b98f..b1e33fa5cf 100644
--- a/libgnucash/core-utils/gnc-locale-utils.c
+++ b/libgnucash/core-utils/gnc-locale-utils.c
@@ -26,8 +26,54 @@
#include <glib.h>
#include <glib/gi18n.h>
-#include <stdlib.h> /* for mbstowcs() */
+#ifdef G_OS_WIN32
+#include <windows.h>
+
+static void
+gnc_lconv_set_utf8 (char **p_value, wchar_t *w_value, const char *default_value)
+{
+ g_return_if_fail (p_value != NULL);
+ if (w_value && *w_value)
+ *p_value = g_utf16_to_utf8 (w_value, -1, NULL, NULL, NULL);
+ else
+ *p_value = g_strdup (default_value);
+}
+
+static LPCWSTR
+get_locale_name ()
+{
+ char* locale = setlocale(LC_MONETARY, NULL);
+ int len = 0;
+ len = strchr (locale, '.') - locale;
+ locale[2] = '-';
+ wchar_t *wlocale = g_utf8_to_utf16 (locale, len, NULL, NULL, NULL);
+ if (IsValidLocaleName(wlocale))
+ return wlocale;
+ return LOCALE_NAME_USER_DEFAULT;
+}
+
+#define BUFSIZE 10 //Max size used by LOCALE_SGROUPING.
+static wchar_t*
+get_lconv_wide_val (LCTYPE lctype)
+{
+ static wchar_t buffer[BUFSIZE];
+ LPCWSTR locale = get_locale_name ();
+ memset (buffer, 0, BUFSIZE * sizeof(wchar_t));
+ int count = GetLocaleInfoEx (locale, lctype, buffer, BUFSIZE);
+ if (!count)
+ {
+ g_error("GetLocaleInfo failed for %ld, %ld", lctype, GetLastError());
+ return NULL;
+ }
+ if (lctype == LOCALE_SGROUPING || lctype == LOCALE_SMONGROUPING)
+ {
+ buffer[0] &= 0x0f; // The standard localeconv is a single uint8
+ buffer[1] = '\0';
+ }
+ return buffer;
+}
+#else
static void
gnc_lconv_set_utf8 (char **p_value, char *default_value)
{
@@ -37,25 +83,7 @@ gnc_lconv_set_utf8 (char **p_value, char *default_value)
if ((value == NULL) || (value[0] == 0))
value = default_value;
-#ifdef G_OS_WIN32
- {
- /* get number of resulting wide characters */
- size_t count = mbstowcs (NULL, value, 0);
- if (count > 0)
- {
- /* malloc and convert */
- wchar_t *wvalue = g_malloc ((count + 1) * sizeof(wchar_t));
- count = mbstowcs (wvalue, value, count + 1);
- if (count > 0)
- {
- *p_value = g_utf16_to_utf8 (wvalue, -1, NULL, NULL, NULL);
- }
- g_free (wvalue);
- }
- }
-#else /* !G_OS_WIN32 */
*p_value = g_locale_to_utf8 (value, -1, NULL, NULL, NULL);
-#endif
if (*p_value == NULL)
{
@@ -65,6 +93,7 @@ gnc_lconv_set_utf8 (char **p_value, char *default_value)
}
}
+#endif
static void
gnc_lconv_set_char (char *p_value, char default_value)
{
@@ -82,7 +111,28 @@ gnc_localeconv (void)
return &lc;
lc = *localeconv();
-
+#ifdef G_OS_WIN32
+ gnc_lconv_set_utf8(&lc.decimal_point,
+ get_lconv_wide_val (LOCALE_SDECIMAL), ".");
+ gnc_lconv_set_utf8(&lc.thousands_sep,
+ get_lconv_wide_val (LOCALE_STHOUSAND),",");
+ gnc_lconv_set_utf8(&lc.grouping,
+ get_lconv_wide_val (LOCALE_SGROUPING), "\003");
+ gnc_lconv_set_utf8(&lc.int_curr_symbol,
+ get_lconv_wide_val (LOCALE_SINTLSYMBOL), "USD ");
+ gnc_lconv_set_utf8(&lc.currency_symbol,
+ get_lconv_wide_val (LOCALE_SCURRENCY), "$");
+ gnc_lconv_set_utf8(&lc.mon_decimal_point,
+ get_lconv_wide_val (LOCALE_SMONDECIMALSEP), ".");
+ gnc_lconv_set_utf8(&lc.mon_thousands_sep,
+ get_lconv_wide_val (LOCALE_SMONTHOUSANDSEP), ",");
+ gnc_lconv_set_utf8(&lc.mon_grouping,
+ get_lconv_wide_val (LOCALE_SMONGROUPING), "\003");
+ gnc_lconv_set_utf8(&lc.negative_sign,
+ get_lconv_wide_val (LOCALE_SNEGATIVESIGN), "-");
+ gnc_lconv_set_utf8(&lc.positive_sign,
+ get_lconv_wide_val (LOCALE_SPOSITIVESIGN), "");
+#else
gnc_lconv_set_utf8(&lc.decimal_point, ".");
gnc_lconv_set_utf8(&lc.thousands_sep, ",");
gnc_lconv_set_utf8(&lc.grouping, "\003");
@@ -93,7 +143,7 @@ gnc_localeconv (void)
gnc_lconv_set_utf8(&lc.mon_grouping, "\003");
gnc_lconv_set_utf8(&lc.negative_sign, "-");
gnc_lconv_set_utf8(&lc.positive_sign, "");
-
+#endif
gnc_lconv_set_char(&lc.frac_digits, 2);
gnc_lconv_set_char(&lc.int_frac_digits, 2);
gnc_lconv_set_char(&lc.p_cs_precedes, 1);
Summary of changes:
libgnucash/core-utils/gnc-locale-utils.c | 92 ++++++++++++++++++++++++--------
1 file changed, 71 insertions(+), 21 deletions(-)
More information about the gnucash-changes
mailing list