Bug 798657 - Import Summary language is wrong

Root cause is using boost::locale::translate because it ignores
the LANGUAGES environment variable and doesn't support different
values for LC_MESSAGES, LC_DATE, LC_MONETARY, and LC_NUMERIC.
That makes it impossible to configure a user environment that
presents translated strings in a different locale from the one
applied to formatting dates and numbers.

To correct this replace all use of boost::locale::translate
with GNU gettext.
This commit is contained in:
John Ralls 2022-12-16 15:25:59 -08:00
parent dd48a025d5
commit 091d4aff22
8 changed files with 60 additions and 59 deletions

View File

@ -129,14 +129,14 @@ Gnucash::GnucashCli::start ([[maybe_unused]] int argc, [[maybe_unused]] char **a
{
if (*m_quotes_cmd != "get")
{
std::cerr << bl::format (bl::translate("Unknown quotes command '{1}'")) % *m_quotes_cmd << "\n\n"
std::cerr << bl::format (std::string{_("Unknown quotes command '{1}'")}) % *m_quotes_cmd << "\n\n"
<< *m_opt_desc_display.get();
return 1;
}
if (!m_file_to_load || m_file_to_load->empty())
{
std::cerr << bl::translate("Missing data file parameter") << "\n\n"
std::cerr << _("Missing data file parameter") << "\n\n"
<< *m_opt_desc_display.get();
return 1;
}
@ -150,7 +150,7 @@ Gnucash::GnucashCli::start ([[maybe_unused]] int argc, [[maybe_unused]] char **a
{
if (!m_file_to_load || m_file_to_load->empty())
{
std::cerr << bl::translate("Missing data file parameter") << "\n\n"
std::cerr << _("Missing data file parameter") << "\n\n"
<< *m_opt_desc_display.get();
return 1;
}
@ -174,7 +174,7 @@ Gnucash::GnucashCli::start ([[maybe_unused]] int argc, [[maybe_unused]] char **a
else if (*m_report_cmd == "show")
if (!m_report_name || m_report_name->empty())
{
std::cerr << bl::translate("Missing --name parameter") << "\n\n"
std::cerr << _("Missing --name parameter") << "\n\n"
<< *m_opt_desc_display.get();
return 1;
}
@ -182,13 +182,13 @@ Gnucash::GnucashCli::start ([[maybe_unused]] int argc, [[maybe_unused]] char **a
return Gnucash::report_show (m_file_to_load, m_report_name);
else
{
std::cerr << bl::format (bl::translate("Unknown report command '{1}'")) % *m_report_cmd << "\n\n"
std::cerr << bl::format (std::string{_("Unknown report command '{1}'")}) % *m_report_cmd << "\n\n"
<< *m_opt_desc_display.get();
return 1;
}
}
std::cerr << bl::translate("Missing command or option") << "\n\n"
std::cerr << _("Missing command or option") << "\n\n"
<< *m_opt_desc_display.get();
return 1;

View File

@ -89,7 +89,7 @@ scm_add_quotes(void *data, [[maybe_unused]] int argc, [[maybe_unused]] char **ar
if (!gnc_quote_source_fq_installed())
{
std::cerr << bl::translate ("No quotes retrieved. Finance::Quote isn't "
std::cerr << _("No quotes retrieved. Finance::Quote isn't "
"installed properly.") << "\n";
scm_cleanup_and_exit_with_failure (nullptr);
}

View File

@ -78,12 +78,12 @@ gnc_print_unstable_message(void)
{
if (!is_development_version) return;
std::cerr << bl::translate ("This is a development version. It may or may not work.") << "\n"
<< bl::translate ("Report bugs and other problems to gnucash-devel@gnucash.org") << "\n"
std::cerr << _("This is a development version. It may or may not work.") << "\n"
<< _("Report bugs and other problems to gnucash-devel@gnucash.org") << "\n"
/* Translators: {1} will be replaced with an URL*/
<< bl::format (bl::translate ("You can also lookup and file bug reports at {1}")) % PACKAGE_BUGREPORT << "\n"
<< bl::format (std::string{_("You can also lookup and file bug reports at {1}")}) % PACKAGE_BUGREPORT << "\n"
/* Translators: {1} will be replaced with an URL*/
<< bl::format (bl::translate ("To find the last stable version, please refer to {1}")) % PACKAGE_URL << "\n";
<< bl::format (std::string{_("To find the last stable version, please refer to {1}")}) % PACKAGE_URL << "\n";
}
static void
@ -100,8 +100,8 @@ Gnucash::gnc_load_scm_config (void)
if (!is_system_config_loaded)
{
/* Translators: Guile is the programming language of the reports */
auto msg = bl::translate ("Loading system wide Guile extensions…").str (gnc_get_boost_locale());
update_message (msg.c_str());
auto msg = _("Loading system wide Guile extensions…");
update_message (msg);
auto system_config_dir = gnc_path_get_pkgsysconfdir ();
auto system_config = g_build_filename (system_config_dir, "config", nullptr);
is_system_config_loaded = gfec_try_load (system_config);
@ -112,8 +112,8 @@ Gnucash::gnc_load_scm_config (void)
static auto is_user_config_loaded = false;
if (!is_user_config_loaded)
{
auto msg = bl::translate ("Loading user specific Guile extensions…").str (gnc_get_boost_locale());
update_message (msg.c_str());
auto msg = _("Loading user specific Guile extensions…");
update_message (msg);
auto config_filename = g_build_filename (gnc_userconfig_dir (), "config-user.scm", nullptr);
is_user_config_loaded = gfec_try_load (config_filename);
g_free (config_filename);
@ -210,6 +210,7 @@ Gnucash::CoreApp::CoreApp ()
gnc_init_boost_locale (localedir);
std::cerr.imbue (gnc_get_boost_locale());
std::cout.imbue (gnc_get_boost_locale());
g_free(localedir);
}
@ -221,9 +222,9 @@ Gnucash::CoreApp::CoreApp (const char* app_name)
m_app_name = std::string(app_name);
// Now that gettext is properly initialized, set our help tagline.
m_tagline = bl::translate("- GnuCash, accounting for personal and small business finance").str(gnc_get_boost_locale());
m_tagline = _("- GnuCash, accounting for personal and small business finance");
m_opt_desc_display = std::make_unique<bpo::options_description>
((bl::format (bl::gettext ("{1} [options] [datafile]", gnc_get_boost_locale())) % m_app_name).str() + std::string(" ") + m_tagline);
((bl::format (std::string{_("{1} [options] [datafile]")}) % m_app_name).str() + std::string(" ") + m_tagline);
add_common_program_options();
}
@ -267,15 +268,15 @@ Gnucash::CoreApp::parse_command_line (int argc, char **argv)
if (m_show_version)
{
bl::format rel_fmt (bl::translate ("GnuCash {1}"));
bl::format dev_fmt (bl::translate ("GnuCash {1} development version"));
bl::format rel_fmt (std::string{_("GnuCash {1}")});
bl::format dev_fmt (std::string{_("GnuCash {1} development version")});
if (is_development_version)
std::cout << dev_fmt % gnc_version () << "\n";
else
std::cout << rel_fmt % gnc_version () << "\n";
std::cout << bl::translate ("Build ID") << ": " << gnc_build_id () << "\n";
std::cout << _("Build ID") << ": " << gnc_build_id () << "\n";
exit(0);
}

View File

@ -170,8 +170,8 @@ scm_run_gnucash (void *data, [[maybe_unused]] int argc, [[maybe_unused]] char **
gnc_hook_add_dangler(HOOK_UI_SHUTDOWN, (GFunc)gnc_file_quit, NULL, NULL);
/* Install Price Quote Sources */
auto msg = bl::translate ("Checking Finance::Quote...").str(gnc_get_boost_locale());
gnc_update_splash_screen (msg.c_str(), GNC_SPLASH_PERCENTAGE_UNKNOWN);
auto msg = _("Checking Finance::Quote...");
gnc_update_splash_screen (msg, GNC_SPLASH_PERCENTAGE_UNKNOWN);
scm_c_use_module("gnucash price-quotes");
scm_c_eval_string("(gnc:price-quotes-install-sources)");
@ -179,8 +179,8 @@ scm_run_gnucash (void *data, [[maybe_unused]] int argc, [[maybe_unused]] char **
if (!user_file_spec->nofile && (fn = get_file_to_load (user_file_spec->file_to_load)) && *fn )
{
auto msg = bl::translate ("Loading data...").str(gnc_get_boost_locale());
gnc_update_splash_screen (msg.c_str(), GNC_SPLASH_PERCENTAGE_UNKNOWN);
auto msg = _("Loading data...");
gnc_update_splash_screen (msg, GNC_SPLASH_PERCENTAGE_UNKNOWN);
gnc_file_open_file(gnc_get_splash_screen(), fn, /*open_readonly*/ FALSE);
g_free(fn);
}
@ -309,11 +309,11 @@ Gnucash::Gnucash::start ([[maybe_unused]] int argc, [[maybe_unused]] char **argv
// Will be removed in 5.0
if (m_add_quotes)
{
std::cerr << bl::translate ("The '--add-price-quotes' option to gnucash has been deprecated and will be removed in GnuCash 5.0. "
"Please use 'gnucash-cli --quotes get <datafile>' instead.") << "\n";
std::cerr << _("The '--add-price-quotes' option to gnucash has been deprecated and will be removed in GnuCash 5.0. "
"Please use 'gnucash-cli --quotes get <datafile>' instead.") << "\n";
if (!m_file_to_load || m_file_to_load->empty())
{
std::cerr << bl::translate("Missing data file parameter") << "\n\n"
std::cerr << _("Missing data file parameter") << "\n\n"
<< *m_opt_desc_display.get();
return 1;
}
@ -345,10 +345,10 @@ main(int argc, char ** argv)
/* We need to initialize gtk before looking up all modules */
if(!gtk_init_check (&argc, &argv))
{
std::cerr << bl::format (bl::translate ("Run '{1} --help' to see a full list of available command line options.")) % *argv[0]
std::cerr << bl::format (std::string{("Run '{1} --help' to see a full list of available command line options.")}) % *argv[0]
<< "\n"
// Translators: Do not translate $DISPLAY! It is an environment variable for X11
<< bl::translate ("Error: could not initialize graphical user interface and option add-price-quotes was not set.\n"
<< _("Error: could not initialize graphical user interface and option add-price-quotes was not set.\n"
"Perhaps you need to set the $DISPLAY environment variable?");
return 1;
}

View File

@ -2122,7 +2122,7 @@ CsvImpTransAssist::assist_summary_page_prepare ()
try
{
/* Translators: {1} will be replaced with a filename */
text += (bl::format (bl::translate ("The transactions were imported from file '{1}'.")) % m_file_name).str(gnc_get_boost_locale());
text += (bl::format (std::string{_("The transactions were imported from file '{1}'.")}) % m_file_name).str();
text += "</b></span>";
}
catch (const bl::conv::conversion_error& err)

View File

@ -235,16 +235,16 @@ void GncImportPrice::set (GncPricePropType prop_type, const std::string& value,
}
catch (const std::invalid_argument& e)
{
auto err_str = (bl::format (bl::translate ("Column '{1}' could not be understood.\n")) %
bl::translate (gnc_price_col_type_strs[prop_type])).str(gnc_get_boost_locale()) +
auto err_str = (bl::format (std::string{_("Column '{1}' could not be understood.\n")}) %
std::string{_(gnc_price_col_type_strs[prop_type])}).str() +
e.what();
m_errors.emplace(prop_type, err_str);
throw std::invalid_argument (err_str);
}
catch (const std::out_of_range& e)
{
auto err_str = (bl::format (bl::translate ("Column '{1}' could not be understood.\n")) %
bl::translate (gnc_price_col_type_strs[prop_type])).str(gnc_get_boost_locale()) +
auto err_str = (bl::format (std::string{_("Column '{1}' could not be understood.\n")}) %
std::string{_(gnc_price_col_type_strs[prop_type])}).str() +
e.what();
m_errors.emplace(prop_type, err_str);
throw std::invalid_argument (err_str);

View File

@ -289,16 +289,16 @@ void GncPreTrans::set (GncTransPropType prop_type, const std::string& value)
}
catch (const std::invalid_argument& e)
{
auto err_str = (bl::format (bl::translate ("Column '{1}' could not be understood.\n")) %
bl::translate (gnc_csv_col_type_strs[prop_type])).str(gnc_get_boost_locale()) +
auto err_str = (bl::format (std::string{_("Column '{1}' could not be understood.\n")}) %
std::string{_(gnc_csv_col_type_strs[prop_type])}).str() +
e.what();
m_errors.emplace(prop_type, err_str);
throw std::invalid_argument (err_str);
}
catch (const std::out_of_range& e)
{
auto err_str = (bl::format (bl::translate ("Column '{1}' could not be understood.\n")) %
bl::translate (gnc_csv_col_type_strs[prop_type])).str(gnc_get_boost_locale()) +
auto err_str = (bl::format (std::string{_("Column '{1}' could not be understood.\n")}) %
std::string{_(gnc_csv_col_type_strs[prop_type])}).str() +
e.what();
m_errors.emplace(prop_type, err_str);
throw std::invalid_argument (err_str);
@ -508,16 +508,16 @@ void GncPreSplit::set (GncTransPropType prop_type, const std::string& value)
}
catch (const std::invalid_argument& e)
{
auto err_str = (bl::format (bl::translate ("Column '{1}' could not be understood.\n")) %
bl::translate (gnc_csv_col_type_strs[prop_type])).str(gnc_get_boost_locale()) +
auto err_str = (bl::format (std::string{_("Column '{1}' could not be understood.\n")}) %
std::string{_(gnc_csv_col_type_strs[prop_type])}).str() +
e.what();
m_errors.emplace(prop_type, err_str);
throw std::invalid_argument (err_str);
}
catch (const std::out_of_range& e)
{
auto err_str = (bl::format (bl::translate ("Column '{1}' could not be understood.\n")) %
bl::translate (gnc_csv_col_type_strs[prop_type])).str(gnc_get_boost_locale()) +
auto err_str = (bl::format (std::string{_("Column '{1}' could not be understood.\n")}) %
std::string{_(gnc_csv_col_type_strs[prop_type])}).str() +
e.what();
m_errors.emplace(prop_type, err_str);
throw std::invalid_argument (err_str);
@ -571,16 +571,16 @@ void GncPreSplit::add (GncTransPropType prop_type, const std::string& value)
}
catch (const std::invalid_argument& e)
{
auto err_str = (bl::format (bl::translate ("Column '{1}' could not be understood.\n")) %
bl::translate (gnc_csv_col_type_strs[prop_type])).str(gnc_get_boost_locale()) +
auto err_str = (bl::format (std::string{_("Column '{1}' could not be understood.\n")}) %
std::string{_(gnc_csv_col_type_strs[prop_type])}).str() +
e.what();
m_errors.emplace(prop_type, err_str);
throw std::invalid_argument (err_str);
}
catch (const std::out_of_range& e)
{
auto err_str = (bl::format (bl::translate ("Column '{1}' could not be understood.\n")) %
bl::translate (gnc_csv_col_type_strs[prop_type])).str(gnc_get_boost_locale()) +
auto err_str = (bl::format (std::string{_("Column '{1}' could not be understood.\n")}) %
std::string{_(gnc_csv_col_type_strs[prop_type])}).str() +
e.what();
m_errors.emplace(prop_type, err_str);
throw std::invalid_argument (err_str);

View File

@ -671,35 +671,35 @@ static std::string migrate_gnc_datahome()
/* Step 3: inform the user of additional changes */
if (full_copy || !succeeded.empty() || !conf_exist_vec.empty() || !failed.empty())
migration_msg << bl::translate ("Notice") << std::endl << std::endl;
migration_msg << _("Notice") << std::endl << std::endl;
if (full_copy)
{
migration_msg
<< bl::translate ("Your gnucash metadata has been migrated.") << std::endl << std::endl
<< _("Your gnucash metadata has been migrated.") << std::endl << std::endl
/* Translators: this refers to a directory name. */
<< bl::translate ("Old location:") << " " << old_dir.string() << std::endl
<< _("Old location:") << " " << old_dir.string() << std::endl
/* Translators: this refers to a directory name. */
<< bl::translate ("New location:") << " " << gnc_userdata_home.string() << std::endl << std::endl
<< _("New location:") << " " << gnc_userdata_home.string() << std::endl << std::endl
// Translators {1} will be replaced with the package name (typically Gnucash) at runtime
<< bl::format (bl::translate ("If you no longer intend to run {1} 2.6.x or older on this system you can safely remove the old directory."))
<< bl::format (std::string{_("If you no longer intend to run {1} 2.6.x or older on this system you can safely remove the old directory.")})
% PACKAGE_NAME;
}
if (full_copy &&
(!succeeded.empty() || !conf_exist_vec.empty() || !failed.empty()))
migration_msg << std::endl << std::endl
<< bl::translate ("In addition:");
<< _("In addition:");
if (!succeeded.empty())
{
migration_msg << std::endl << std::endl;
if (full_copy)
migration_msg << bl::format (bl::translate ("The following file has been copied to {1} instead:",
migration_msg << bl::format (std::string{ngettext("The following file has been copied to {1} instead:",
"The following files have been copied to {1} instead:",
succeeded.size())) % gnc_userconfig_home.string().c_str();
succeeded.size())}) % gnc_userconfig_home.string().c_str();
else
migration_msg << bl::format (bl::translate ("The following file in {1} has been renamed:"))
migration_msg << bl::format (std::string{_("The following file in {1} has been renamed:")})
% gnc_userconfig_home.string().c_str();
migration_msg << std::endl;
@ -708,8 +708,8 @@ static std::string migrate_gnc_datahome()
}
if (!conf_exist_vec.empty())
{
migration_msg << std::endl << std::endl
<< bl::translate ("The following file has become obsolete and will be ignored:",
migration_msg << "\n\n"
<< ngettext("The following file has become obsolete and will be ignored:",
"The following files have become obsolete and will be ignored:",
conf_exist_vec.size())
<< std::endl;
@ -719,9 +719,9 @@ static std::string migrate_gnc_datahome()
if (!failed.empty())
{
migration_msg << std::endl << std::endl
<< bl::format (bl::translate ("The following file could not be moved to {1}:",
<< bl::format (std::string{ngettext("The following file could not be moved to {1}:",
"The following files could not be moved to {1}:",
failed.size())) % gnc_userconfig_home.string().c_str()
failed.size())}) % gnc_userconfig_home.string().c_str()
<< std::endl;
for (auto failed_file : failed)
migration_msg << "- " << failed_file << std::endl;