Replace all instances of naked vgettext() calls with VGETTEXT()

The vgettext() function, while declared in src/formula/string_utils.hpp,
actually has its implementation out-of-line in
src/formula/string_utils.cpp where GETTEXT_TEXTDOMAIN is defined to
"wesnoth-lib". Because vgettext() is implemented in terms of the _()
function (an inline wrapper around translation::dsgettext()), it passes
the textdomain defined in the file where it was implemented as a
parameter.

This means that every case of vgettext() being used in other code units
where GETTEXT_TEXTDOMAIN is not defined to "wesnoth-lib", is broken if
the string being looked upon doesn't coincidentally exist in the
wesnoth-lib textdomain.

Ages ago, to work around this limitation, an overload of vgettext() that
takes the textdomain name as a parameter was introduced (see commit
0ba3d05204). Since this form of vgettext()
is rather unwieldy to use (and in particular, the xgettext message
extraction tool mistakes the first argument for the msgid, see below), a
VGETTEXT() macro was also added that uses the GETTEXT_TEXTDOMAIN symbol
defined in the file where the call is made, and thus we get the correct
string from the correct textdomain.

Switching all cases of naked vgettext() in mainline to VGETTEXT() fixes
a myriad of situations where an interpolated string that has an extant
translation does not actually get translated in practice because of the
mismatched textdomain reference (see issue #2709 for an example with MP
game titles). I couldn't find any cases of the companion vngettext()
function (which handles plurals) being used in the wild naked, but for
future reference it also has a companion VNGETTEXT() macro to pass the
correct textdomain to its textdomain-parameter overload.

One caveat is that this commit DOES break the string freeze in one
particular case -- src/units/unit.cpp has a case where the
textdomain-parameter version of naked vgettext() was in use with
"wesnoth" as the first parameter, and xgettext misidentified this as a
translation entry for a "wesnoth" string in the file's assigned
textdomain (which is the default textdomain, wesnoth). So this will
result in the next pot-update both removing the spurious "wesnoth"
string AND adding the correct string to the relevant catalogue template
("<span color=\"$color\">$number_or_percent</span> HP").
to that textdomain.

Other than that, I believe this does not break the string freeze in any
other fashion and it shouldn't result in any regressions for i18n.

It might be worth considering in the future renaming vgettext() and
vngettext() to names that make people less likely to misidentify them as
functions they can freely call directly without regard to the textdomain
assignment issue.

(cherry-picked from commit c5b3947e4a)
This commit is contained in:
Iris Morelle 2018-03-22 05:51:49 -03:00
parent 6f1263d34d
commit 1ef6c5b2c0
39 changed files with 106 additions and 107 deletions

View file

@ -1151,7 +1151,7 @@ namespace { // Private helpers for move_unit()
// Both friends and enemies sighted -- neutral message.
symbols["friendphrase"] = VNGETTEXT("Part of 'Units sighted! (...)' sentence^1 friendly", "$friends friendly", friend_count_, symbols);
symbols["enemyphrase"] = VNGETTEXT("Part of 'Units sighted! (...)' sentence^1 enemy", "$enemies enemy", enemy_count_, symbols);
message = vgettext("Units sighted! ($friendphrase, $enemyphrase)", symbols);
message = VGETTEXT("Units sighted! ($friendphrase, $enemyphrase)", symbols);
msg_color = font::NORMAL_COLOR;
} else if ( enemy_count_ != 0 ) {
// Only enemies sighted -- bad message.
@ -1174,7 +1174,7 @@ namespace { // Private helpers for move_unit()
if ( !name.empty() ) {
utils::string_map symbols;
symbols["hotkey"] = name;
std::string message = vgettext("(press $hotkey to keep moving)", symbols);
std::string message = VGETTEXT("(press $hotkey to keep moving)", symbols);
disp.announce(message_prefix + message, font::NORMAL_COLOR, announce_options);
message_prefix += " \n";
}

View file

@ -72,7 +72,7 @@ void addons_client::connect()
conn_.reset(new network_asio::connection(host_, port_));
this->wait_for_transfer_done(
vgettext("Connecting to $server_address|...", i18n_symbols),
VGETTEXT("Connecting to $server_address|...", i18n_symbols),
transfer_mode::connect);
}
@ -124,7 +124,7 @@ bool addons_client::upload_addon(const std::string& id, std::string& response_me
if(!addon_name_legal(id)){
i18n_symbols["addon_id"] = font::escape_text(id);
this->last_error_ =
vgettext("The add-on <i>$addon_title</i> has an invalid id '$addon_id' "
VGETTEXT("The add-on <i>$addon_title</i> has an invalid id '$addon_id' "
"and cannot be published.", i18n_symbols);
return false;
}
@ -150,7 +150,7 @@ bool addons_client::upload_addon(const std::string& id, std::string& response_me
archive_addon(id, addon_data);
} catch(utf8::invalid_utf8_exception&){
this->last_error_ =
vgettext("The add-on <i>$addon_title</i> has a file or directory "
VGETTEXT("The add-on <i>$addon_title</i> has a file or directory "
"containing invalid characters and cannot be published.", i18n_symbols);
return false;
}
@ -158,7 +158,7 @@ bool addons_client::upload_addon(const std::string& id, std::string& response_me
std::vector<std::string> badnames;
if(!check_names_legal(addon_data, &badnames)){
this->last_error_ =
vgettext("The add-on <i>$addon_title</i> has an invalid file or directory "
VGETTEXT("The add-on <i>$addon_title</i> has an invalid file or directory "
"name and cannot be published. "
"File or directory names may not contain '..' or end with '.' or be longer than 255 characters. "
@ -169,7 +169,7 @@ bool addons_client::upload_addon(const std::string& id, std::string& response_me
}
if(!check_case_insensitive_duplicates(addon_data, &badnames)){
this->last_error_ =
vgettext("The add-on <i>$addon_title</i> contains files or directories with case conflicts. "
VGETTEXT("The add-on <i>$addon_title</i> contains files or directories with case conflicts. "
"File or directory names may not be differently-cased versions of the same string.", i18n_symbols);
this->last_error_data_ = font::escape_text(utils::join(badnames, "\n"));
return false;
@ -181,7 +181,7 @@ bool addons_client::upload_addon(const std::string& id, std::string& response_me
LOG_ADDONS << "sending " << id << '\n';
this->send_request(request_buf, response_buf);
this->wait_for_transfer_done(vgettext("Sending add-on <i>$addon_title</i>...", i18n_symbols
this->wait_for_transfer_done(VGETTEXT("Sending add-on <i>$addon_title</i>...", i18n_symbols
), transfer_mode::upload);
if(const config& message_cfg = response_buf.child("message")) {
@ -214,7 +214,7 @@ bool addons_client::delete_remote_addon(const std::string& id, std::string& resp
LOG_ADDONS << "requesting server to delete " << id << '\n';
this->send_request(request_buf, response_buf);
this->wait_for_transfer_done(vgettext("Removing add-on <i>$addon_title</i> from the server...", i18n_symbols
this->wait_for_transfer_done(VGETTEXT("Removing add-on <i>$addon_title</i> from the server...", i18n_symbols
));
if(const config& message_cfg = response_buf.child("message")) {
@ -241,7 +241,7 @@ bool addons_client::download_addon(config& archive_cfg, const std::string& id, c
LOG_ADDONS << "downloading " << id << '\n';
this->send_request(request_buf, archive_cfg);
this->wait_for_transfer_done(vgettext("Downloading add-on <i>$addon_title</i>...", i18n_symbols));
this->wait_for_transfer_done(VGETTEXT("Downloading add-on <i>$addon_title</i>...", i18n_symbols));
return !this->update_last_error(archive_cfg);
}
@ -255,13 +255,13 @@ bool addons_client::install_addon(config& archive_cfg, const addon_info& info)
if(!check_names_legal(archive_cfg)) {
gui2::show_error_message(
vgettext("The add-on <i>$addon_title</i> has an invalid file or directory "
VGETTEXT("The add-on <i>$addon_title</i> has an invalid file or directory "
"name and cannot be installed.", i18n_symbols));
return false;
}
if(!check_case_insensitive_duplicates(archive_cfg)){
gui2::show_error_message(
vgettext("The add-on <i>$addon_title</i> has file or directory names "
VGETTEXT("The add-on <i>$addon_title</i> has file or directory names "
"with case conflicts. This may cause problems.", i18n_symbols));
}
@ -446,7 +446,7 @@ bool addons_client::do_check_before_overwriting_addon(const addon_info& addon)
std::string text;
std::vector<std::string> extra_items;
text = vgettext("The add-on '$addon|' is already installed and contains additional information that will be permanently lost if you continue:", symbols);
text = VGETTEXT("The add-on '$addon|' is already installed and contains additional information that will be permanently lost if you continue:", symbols);
text += "\n\n";
if(pbl) {

View file

@ -94,7 +94,7 @@ bool addons_manager_ui(const std::string& remote_address)
symbols["msg"] = e.message;
gui2::show_error_message(
vgettext("A local file with add-on publishing information could not be read.\n\nFile: $path\nError message: $msg", symbols));
VGETTEXT("A local file with add-on publishing information could not be read.\n\nFile: $path\nError message: $msg", symbols));
} catch(wml_exception& e) {
e.show();
} catch(const addons_client::user_exit&) {
@ -281,7 +281,7 @@ bool ad_hoc_addon_fetch_session(const std::vector<std::string>& addon_ids)
} else {
utils::string_map symbols;
symbols["addon_id"] = addon_id;
gui2::show_error_message(vgettext("Could not find an add-on matching id $addon_id on the add-on server.", symbols));
gui2::show_error_message(VGETTEXT("Could not find an add-on matching id $addon_id on the add-on server.", symbols));
return_value = false;
}
}
@ -305,7 +305,7 @@ bool ad_hoc_addon_fetch_session(const std::vector<std::string>& addon_ids)
symbols["msg"] = e.message;
gui2::show_error_message(
vgettext("A local file with add-on publishing information could not be read.\n\nFile: $path\nError message: $msg", symbols));
VGETTEXT("A local file with add-on publishing information could not be read.\n\nFile: $path\nError message: $msg", symbols));
} catch(wml_exception& e) {
e.show();
} catch(const addons_client::user_exit&) {

View file

@ -58,7 +58,7 @@ void chat_handler::change_logging(const std::string& data) {
utils::string_map symbols;
symbols["level"] = level;
const std::string& msg =
vgettext("Unknown debug level: '$level'.", symbols);
VGETTEXT("Unknown debug level: '$level'.", symbols);
ERR_NG << msg << std::endl;
add_chat_message(time(nullptr), _("error"), 0, msg);
return;
@ -67,7 +67,7 @@ void chat_handler::change_logging(const std::string& data) {
utils::string_map symbols;
symbols["domain"] = domain;
const std::string& msg =
vgettext("Unknown debug domain: '$domain'.", symbols);
VGETTEXT("Unknown debug domain: '$domain'.", symbols);
ERR_NG << msg << std::endl;
add_chat_message(time(nullptr), _("error"), 0, msg);
return;
@ -77,7 +77,7 @@ void chat_handler::change_logging(const std::string& data) {
symbols["level"] = level;
symbols["domain"] = domain;
const std::string& msg =
vgettext("Switched domain: '$domain' to level: '$level'.", symbols);
VGETTEXT("Switched domain: '$domain' to level: '$level'.", symbols);
LOG_NG << msg << "\n";
add_chat_message(time(nullptr), "log", 0, msg);
}

View file

@ -907,7 +907,7 @@ void context_manager::load_map(const std::string& filename, bool new_context)
symbols["map_data"] = get_map_context().get_map_data_key();
gui2::show_transient_message(_("Map loaded from scenario"),
//TODO: msg is already translated does vgettext make sense?
vgettext(msg.c_str(), symbols));
VGETTEXT(msg.c_str(), symbols));
}
}
}

View file

@ -33,7 +33,7 @@ editor_map_load_exception wrap_exc(const char* type, const std::string& e_msg, c
utils::string_map symbols;
symbols["type"] = type;
const char* error_msg = "There was an error ($type) while loading the file:";
std::string msg = vgettext(error_msg, symbols);
std::string msg = VGETTEXT(error_msg, symbols);
msg += "\n";
msg += e_msg;
return editor_map_load_exception(filename, msg);
@ -145,7 +145,7 @@ std::set<map_location> editor_map::set_starting_position_labels(display& disp)
bool is_number = std::find_if(pair.first.begin(), pair.first.end(), [](char c) { return !std::isdigit(c); }) == pair.first.end();
if (is_number) {
label = vgettext("Player $side_num", utils::string_map{ { "side_num", pair.first } });
label = VGETTEXT("Player $side_num", utils::string_map{ { "side_num", pair.first } });
}
else {
label = pair.first;

View file

@ -597,7 +597,7 @@ bool map_context::save_scenario()
} catch(filesystem::io_exception& e) {
utils::string_map symbols;
symbols["msg"] = e.what();
const std::string msg = vgettext("Could not save the scenario: $msg", symbols);
const std::string msg = VGETTEXT("Could not save the scenario: $msg", symbols);
throw editor_map_save_exception(msg);
}
@ -639,7 +639,7 @@ bool map_context::save_map()
} catch(filesystem::io_exception& e) {
utils::string_map symbols;
symbols["msg"] = e.what();
const std::string msg = vgettext("Could not save the map: $msg", symbols);
const std::string msg = VGETTEXT("Could not save the map: $msg", symbols);
throw editor_map_save_exception(msg);
}

View file

@ -108,7 +108,7 @@ public:
id_ = id;
bool is_number = std::find_if(id.begin(), id.end(), [](char c) { return !std::isdigit(c); }) == id.end();
if (is_number) {
desc_ = vgettext("Player $side_num", utils::string_map{ {"side_num", id} });
desc_ = VGETTEXT("Player $side_num", utils::string_map{ {"side_num", id} });
}
else {
desc_ = "";

View file

@ -62,7 +62,7 @@ std::string configure_engine::game_name_default()
{
utils::string_map i18n_symbols;
i18n_symbols["login"] = preferences::login();
return vgettext("$login|s game", i18n_symbols);
return VGETTEXT("$login|s game", i18n_symbols);
}
int configure_engine::num_turns_default() const

View file

@ -1039,7 +1039,7 @@ config side_engine::new_config() const
if(!desc.empty()) {
res["user_description"] = t_string(desc, "wesnoth");
desc = vgettext("$playername $side", {
desc = VGETTEXT("$playername $side", {
{"playername", _(desc.c_str())},
{"side", res["side"].str()}
});

View file

@ -213,7 +213,7 @@ void flg_manager::resolve_random(randomness::mt_rng& rng, const std::vector<std:
}
if(nonrandom_leaders.empty()) {
throw config::error(vgettext(
throw config::error(VGETTEXT(
"Unable to find a leader type for faction $faction", {{"faction", (*current_faction_)["name"].str()}}));
} else {
const int lchoice = rng.get_next_random() % nonrandom_leaders.size();
@ -237,7 +237,7 @@ void flg_manager::resolve_random(randomness::mt_rng& rng, const std::vector<std:
const int gchoice = rng.get_next_random() % nonrandom_genders.size();
current_gender_ = nonrandom_genders[gchoice];
} else {
throw config::error(vgettext("Cannot obtain genders for invalid leader $leader", {{"leader", current_leader_}}));
throw config::error(VGETTEXT("Cannot obtain genders for invalid leader $leader", {{"leader", current_leader_}}));
}
}
}

View file

@ -234,9 +234,9 @@ game_info::game_info(const config& game, const config& game_config, const std::v
// Use addon name if provided, else fall back on the addon id.
if(addon.has_attribute("name")) {
r.message = vgettext("Missing addon: $name", {{"name", addon["name"].str()}});
r.message = VGETTEXT("Missing addon: $name", {{"name", addon["name"].str()}});
} else {
r.message = vgettext("Missing addon: $id", {{"id", addon["id"].str()}});
r.message = VGETTEXT("Missing addon: $id", {{"id", addon["id"].str()}});
}
required_addons.push_back(std::move(r));
@ -261,7 +261,7 @@ game_info::game_info(const config& game, const config& game_config, const std::v
addons_outcome = std::max(addons_outcome, result); // Elevate to most severe error level encountered so far
} else {
have_era = !game["require_era"].to_bool(true);
era = vgettext("$era_name (missing)", {{"era_name", game["mp_era_name"].str()}});
era = VGETTEXT("$era_name (missing)", {{"era_name", game["mp_era_name"].str()}});
era_short = make_short_name(era);
verified = false;
@ -492,7 +492,7 @@ game_info::ADDON_REQ game_info::check_addon_version_compatibility(const config&
if(local_min_ver > remote_ver) {
r.outcome = CANNOT_SATISFY;
r.message = vgettext("The host's version of <i>$addon</i> is incompatible. They have version <b>$host_ver</b> while you have version <b>$local_ver</b>.", {
r.message = VGETTEXT("The host's version of <i>$addon</i> is incompatible. They have version <b>$host_ver</b> while you have version <b>$local_ver</b>.", {
{"addon", local_item["addon_title"].str()},
{"host_ver", remote_ver.str()},
{"local_ver", local_ver.str()}
@ -506,7 +506,7 @@ game_info::ADDON_REQ game_info::check_addon_version_compatibility(const config&
if(remote_min_ver > local_ver) {
r.outcome = NEED_DOWNLOAD;
r.message = vgettext("Your version of <i>$addon</i> is incompatible. You have version <b>$local_ver</b> while the host has version <b>$host_ver</b>.", {
r.message = VGETTEXT("Your version of <i>$addon</i> is incompatible. You have version <b>$local_ver</b> while the host has version <b>$host_ver</b>.", {
{"addon", local_item["addon_title"].str()},
{"host_ver", remote_ver.str()},
{"local_ver", local_ver.str()}

View file

@ -98,7 +98,7 @@ config initial_level_config(saved_game& state)
if(!era_cfg) {
if(!params.saved_game) {
throw config::error(vgettext("Cannot find era $era", {{"era", era}}));
throw config::error(VGETTEXT("Cannot find era $era", {{"era", era}}));
}
// FIXME: @todo We should tell user about missing era but still load game...

View file

@ -121,7 +121,7 @@ std::pair<wesnothd_connection_ptr, config> open_connection(std::string host)
i18n_symbols["required_version"] = version;
i18n_symbols["your_version"] = game_config::version;
const std::string errorstring = vgettext("The server accepts versions '$required_version', but you are using version '$your_version'", i18n_symbols);
const std::string errorstring = VGETTEXT("The server accepts versions '$required_version', but you are using version '$your_version'", i18n_symbols);
throw wesnothd_error(errorstring);
}
@ -215,7 +215,7 @@ std::pair<wesnothd_connection_ptr, config> open_connection(std::string host)
std::string warning_msg;
if((*warning)["warning_code"] == MP_NAME_INACTIVE_WARNING) {
warning_msg = vgettext("The nickname $nick is inactive. "
warning_msg = VGETTEXT("The nickname $nick is inactive. "
"You cannot claim ownership of this nickname until you "
"activate your account via email or ask an "
"administrator to do it for you.", {{"nick", login}});
@ -322,23 +322,23 @@ std::pair<wesnothd_connection_ptr, config> open_connection(std::string host)
if((*error)["error_code"] == MP_MUST_LOGIN) {
error_message = _("You must login first.");
} else if((*error)["error_code"] == MP_NAME_TAKEN_ERROR) {
error_message = vgettext("The nickname $nick is already taken.", i18n_symbols);
error_message = VGETTEXT("The nickname $nick is already taken.", i18n_symbols);
} else if((*error)["error_code"] == MP_INVALID_CHARS_IN_NAME_ERROR) {
error_message = vgettext("The nickname $nick contains invalid "
error_message = VGETTEXT("The nickname $nick contains invalid "
"characters. Only alpha-numeric characters (one at minimum), underscores and "
"hyphens are allowed.", i18n_symbols);
} else if((*error)["error_code"] == MP_NAME_TOO_LONG_ERROR) {
error_message = vgettext("The nickname $nick is too long. Nicks must "
error_message = VGETTEXT("The nickname $nick is too long. Nicks must "
"be 20 characters or less.", i18n_symbols);
} else if((*error)["error_code"] == MP_NAME_RESERVED_ERROR) {
error_message = vgettext("The nickname $nick is reserved and cannot be used by players.", i18n_symbols);
error_message = VGETTEXT("The nickname $nick is reserved and cannot be used by players.", i18n_symbols);
} else if((*error)["error_code"] == MP_NAME_UNREGISTERED_ERROR) {
error_message = vgettext("The nickname $nick is not registered on this server.", i18n_symbols)
error_message = VGETTEXT("The nickname $nick is not registered on this server.", i18n_symbols)
+ _(" This server disallows unregistered nicknames.");
} else if((*error)["error_code"] == MP_PASSWORD_REQUEST) {
error_message = vgettext("The nickname $nick is registered on this server.", i18n_symbols);
error_message = VGETTEXT("The nickname $nick is registered on this server.", i18n_symbols);
} else if((*error)["error_code"] == MP_PASSWORD_REQUEST_FOR_LOGGED_IN_NAME) {
error_message = vgettext("The nickname $nick is registered on this server.", i18n_symbols)
error_message = VGETTEXT("The nickname $nick is registered on this server.", i18n_symbols)
+ "\n\n" + _("WARNING: There is already a client using this nickname, "
"logging in will cause that client to be kicked!");
} else if((*error)["error_code"] == MP_NO_SEED_ERROR) {

View file

@ -35,7 +35,7 @@ std::vector<linked_group_definition> parse_linked_group_definitions(const config
VALIDATE(!linked_group.id.empty(), missing_mandatory_wml_key("linked_group", "id"));
if(!linked_group.fixed_width && !linked_group.fixed_height) {
const t_string msg = vgettext(
const t_string msg = VGETTEXT(
"Linked group '$id' needs a 'fixed_width' or 'fixed_height' key.", {{"id", linked_group.id}});
FAIL(msg);

View file

@ -55,7 +55,7 @@ window* build(const builder_window::window_resolution* definition)
for(const auto& lg : definition->linked_groups) {
if(win->has_linked_size_group(lg.id)) {
t_string msg = vgettext("Linked '$id' group has multiple definitions.", {{"id", lg.id}});
t_string msg = VGETTEXT("Linked '$id' group has multiple definitions.", {{"id", lg.id}});
FAIL(msg);
}

View file

@ -764,7 +764,7 @@ void addon_manager::publish_addon(const addon_info& addon, window& window)
void addon_manager::delete_addon(const addon_info& addon, window& window)
{
const std::string addon_id = addon.id;
const std::string& text = vgettext(
const std::string& text = VGETTEXT(
"Deleting '$addon|' will permanently erase its download and upload counts on the add-ons server. Do you really wish to continue?",
{{"addon", make_addon_title(addon_id)}} // FIXME: need the real title!
);
@ -797,7 +797,7 @@ void addon_manager::execute_default_action(const addon_info& addon, window& wind
if(!tracking_info_[addon.id].can_publish) {
utils::string_map symbols{ { "addon", addon.display_title() } };
int res = gui2::show_message(_("Uninstall add-on"),
vgettext("Do you want to uninstall '$addon|'?", symbols),
VGETTEXT("Do you want to uninstall '$addon|'?", symbols),
gui2::dialogs::message::ok_cancel_buttons);
if(res == gui2::retval::OK) {
uninstall_addon(addon, window);

View file

@ -63,11 +63,11 @@ depcheck_confirm_change::depcheck_confirm_change(
symbols["requester"] = requester;
std::string message;
if(action) {
message = vgettext("$requester requires the following modifications to "
message = VGETTEXT("$requester requires the following modifications to "
"be enabled:",
symbols);
} else {
message = vgettext("$requester requires the following modifications to "
message = VGETTEXT("$requester requires the following modifications to "
"be disabled:",
symbols);
}

View file

@ -327,13 +327,13 @@ bool file_dialog::process_submit_common(window& window, const std::string& name)
// We get here in save mode or not. Use the file creation language only in
// save mode.
if(save_mode_) {
show_transient_error_message(vgettext("The file or folder $path cannot be created.", {{"path", name}}));
show_transient_error_message(VGETTEXT("The file or folder $path cannot be created.", {{"path", name}}));
break;
}
FALLTHROUGH;
case SELECTION_NOT_FOUND:
// We only get here if we aren't in save mode.
show_transient_error_message(vgettext("The file or folder $path does not exist.", {{"path", name}}));
show_transient_error_message(VGETTEXT("The file or folder $path does not exist.", {{"path", name}}));
break;
case SELECTION_IS_FILE:
// TODO: Adapt for implementing directory selection mode.
@ -708,7 +708,7 @@ void file_dialog::on_dir_create_cmd(window& window)
if(!fs::make_directory(new_path)) {
show_transient_error_message(
vgettext("Could not create a new folder at $path|. Make sure you have the appropriate permissions to write to this location.",
VGETTEXT("Could not create a new folder at $path|. Make sure you have the appropriate permissions to write to this location.",
{{"path", new_path}}));
} else {
refresh_fileview(window);
@ -740,7 +740,7 @@ void file_dialog::on_file_delete_cmd(window& window)
if(!result) {
show_transient_error_message(
vgettext("Could not delete $path|. Make sure you have the appropriate permissions to write to this location.",
VGETTEXT("Could not delete $path|. Make sure you have the appropriate permissions to write to this location.",
{{"path", selection}}));
} else {
refresh_fileview(window);

View file

@ -320,7 +320,7 @@ void game_load::evaluate_summary_string(std::stringstream& str, const config& cf
symbols["campaign_name"] = "(" + campaign_id + ")";
}
str << vgettext("Campaign: $campaign_name", symbols);
str << VGETTEXT("Campaign: $campaign_name", symbols);
// Display internal id for debug purposes if we didn't above
if(game_config::debug && (campaign != nullptr)) {

View file

@ -73,7 +73,7 @@ label_settings::label_settings(display_context& dc) : viewer(dc) {
string_map subst;
subst["side_number"] = std::to_string(i + 1);
subst["name"] = team_name;
labels_display[label_cat_key] = vgettext("Side $side_number ($name)", subst);
labels_display[label_cat_key] = VGETTEXT("Side $side_number ($name)", subst);
}
}

View file

@ -404,7 +404,7 @@ void mp_lobby::update_gamelist_diff()
void mp_lobby::update_gamelist_header()
{
#ifndef GUI2_EXPERIMENTAL_LISTBOX
const std::string games_string = vgettext("Games: showing $num_shown out of $num_total", {
const std::string games_string = VGETTEXT("Games: showing $num_shown out of $num_total", {
{"num_shown", std::to_string(lobby_info_.games_visibility().count())},
{"num_total", std::to_string(lobby_info_.games().size())}
});

View file

@ -105,7 +105,7 @@ void mp_change_control::pre_show(window& window)
std::map<std::string, string_map> data;
string_map item;
std::string side_str = vgettext("Side $side", {{"side", std::to_string(side)}});
std::string side_str = VGETTEXT("Side $side", {{"side", std::to_string(side)}});
side_str = font::span_color(team::get_side_color(side)) + side_str + "</span>";
item["id"] = (formatter() << "side_" << side).str();

View file

@ -249,7 +249,7 @@ static std::string generate_user_description(const config& side)
} else if(controller_type == "null") {
return _("Empty slot");
} else if(controller_type == "reserved") {
return vgettext("Reserved for $playername", {{"playername", reservation}});
return VGETTEXT("Reserved for $playername", {{"playername", reservation}});
} else if(owner.empty()) {
return _("Vacant slot");
} else if(controller_type == "human" || controller_type == "network") {

View file

@ -871,7 +871,7 @@ void preferences_dialog::add_hotkey_callback(listbox& hotkeys)
}
if(oldhk && oldhk->get_command() != "null") {
const std::string text = vgettext("“<b>$hotkey_sequence|</b>” is in use by “<b>$old_hotkey_action|</b>”.\nDo you wish to reassign it to “<b>$new_hotkey_action|</b>”?", {
const std::string text = VGETTEXT("“<b>$hotkey_sequence|</b>” is in use by “<b>$old_hotkey_action|</b>”.\nDo you wish to reassign it to “<b>$new_hotkey_action|</b>”?", {
{"hotkey_sequence", oldhk->get_name()},
{"old_hotkey_action", hotkey::get_description(oldhk->get_command())},
{"new_hotkey_action", hotkey::get_description(newhk->get_command())}

View file

@ -260,7 +260,7 @@ void chatbox::add_whisper_sent(const std::string& receiver, const std::string& m
switch_to_window(t);
add_active_window_message(preferences::login(), message, true);
} else {
add_active_window_whisper(vgettext("whisper to $receiver", {{"receiver", receiver}}), message, true);
add_active_window_whisper(VGETTEXT("whisper to $receiver", {{"receiver", receiver}}), message, true);
}
lobby_info_->get_whisper_log(receiver).add_message(preferences::login(), message);
@ -393,11 +393,11 @@ lobby_chat_window* chatbox::find_or_create_window(const std::string& name,
item["use_markup"] = "true";
if(whisper) {
item["label"] = vgettext("Whisper session with <i>“$name”</i> started. "
item["label"] = VGETTEXT("Whisper session with <i>“$name”</i> started. "
"If you do not want to receive messages from this user, type <i>/ignore $name</i>\n", {{"name", name}});
data.emplace("log_text", item);
} else {
item["label"] = vgettext("Room <i>“$name”</i> joined", {{"name", name}});
item["label"] = VGETTEXT("Room <i>“$name”</i> joined", {{"name", name}});
data.emplace("log_text", item);
lobby_info_->open_room(name);
@ -594,7 +594,7 @@ void chatbox::process_room_join(const ::config& data)
r->add_member(player);
/* TODO: add/use preference */
add_room_window_message(room, "server", vgettext("$player has entered the room", {{"player", player}}));
add_room_window_message(room, "server", VGETTEXT("$player has entered the room", {{"player", player}}));
}
if(r == active_window_room()) {
@ -636,7 +636,7 @@ void chatbox::process_room_part(const ::config& data)
r->remove_member(player);
/* TODO: add/use preference */
add_room_window_message(room, "server", vgettext("$player has left the room", {{"player", player}}));
add_room_window_message(room, "server", VGETTEXT("$player has left the room", {{"player", player}}));
if(active_window_room() == r) {
active_window_changed_callback_();
}

View file

@ -93,7 +93,7 @@ std::string encode_text_alignment(const PangoAlignment alignment)
t_string missing_widget(const std::string& id)
{
return t_string(vgettext("Mandatory widget '$id' hasn't been defined.", {{"id", id}}));
return t_string(VGETTEXT("Mandatory widget '$id' hasn't been defined.", {{"id", id}}));
}
void get_screen_size_variables(wfl::map_formula_callable& variable)

View file

@ -261,7 +261,7 @@ void unit_preview_pane::set_displayed_type(const unit_type& type)
}
if(label_level_) {
std::string l_str = vgettext("Lvl $lvl", {{"lvl", std::to_string(type.level())}});
std::string l_str = VGETTEXT("Lvl $lvl", {{"lvl", std::to_string(type.level())}});
label_level_->set_label("<b>" + l_str + "</b>");
label_level_->set_use_markup(true);
@ -291,7 +291,7 @@ void unit_preview_pane::set_displayed_type(const unit_type& type)
str << font::span_color(font::unit_type_color) << type.type_name() << "</span>" << "\n";
std::string l_str = vgettext("Lvl $lvl", {{"lvl", std::to_string(type.level())}});
std::string l_str = VGETTEXT("Lvl $lvl", {{"lvl", std::to_string(type.level())}});
str << l_str << "\n";
str << type.alignment() << "\n";
@ -412,7 +412,7 @@ void unit_preview_pane::set_displayed_unit(const unit& u)
}
if(label_level_) {
std::string l_str = vgettext("Lvl $lvl", {{"lvl", std::to_string(u.level())}});
std::string l_str = VGETTEXT("Lvl $lvl", {{"lvl", std::to_string(u.level())}});
label_level_->set_label("<b>" + l_str + "</b>");
label_level_->set_use_markup(true);
@ -443,7 +443,7 @@ void unit_preview_pane::set_displayed_unit(const unit& u)
str << font::span_color(font::unit_type_color) << u.type_name() << "</span>" << "\n";
std::string l_str = vgettext("Lvl $lvl", {{"lvl", std::to_string(u.level())}});
std::string l_str = VGETTEXT("Lvl $lvl", {{"lvl", std::to_string(u.level())}});
str << l_str << "\n";
str << u.alignment() << "\n";

View file

@ -209,7 +209,7 @@ void play_controller::hotkey_handler::toggle_accelerated_speed()
{
utils::string_map symbols;
symbols["hk"] = hotkey::get_names(hotkey::hotkey_command::get_command_by_command(hotkey::HOTKEY_ACCELERATED).command);
gui()->announce(_("Accelerated speed enabled!") + "\n" + vgettext("(press $hk to disable)", symbols), font::NORMAL_COLOR);
gui()->announce(_("Accelerated speed enabled!") + "\n" + VGETTEXT("(press $hk to disable)", symbols), font::NORMAL_COLOR);
}
else
{

View file

@ -141,7 +141,7 @@ void playsingle_controller::hotkey_handler::whiteboard_toggle() {
utils::string_map symbols;
symbols["hotkey"] = hk;
gui()->announce(_("Planning mode activated!") + std::string("\n") + vgettext("(press $hotkey to deactivate)", symbols), font::NORMAL_COLOR);
gui()->announce(_("Planning mode activated!") + std::string("\n") + VGETTEXT("(press $hotkey to deactivate)", symbols), font::NORMAL_COLOR);
} else {
gui()->announce(_("Planning mode deactivated!"), font::NORMAL_COLOR);
}

View file

@ -191,7 +191,7 @@ void menu_handler::save_map()
} catch(filesystem::io_exception& e) {
utils::string_map symbols;
symbols["msg"] = e.what();
const std::string msg = vgettext("Could not save the map: $msg", symbols);
const std::string msg = VGETTEXT("Could not save the map: $msg", symbols);
gui2::show_transient_error_message(msg);
}
}
@ -1370,7 +1370,7 @@ void menu_handler::do_search(const std::string& new_search)
// Not found, inform the player
utils::string_map symbols;
symbols["search"] = last_search_;
const std::string msg = vgettext("Could not find label or unit "
const std::string msg = VGETTEXT("Could not find label or unit "
"containing the string $search.",
symbols);
(void) gui2::show_message("", msg, gui2::dialogs::message::auto_close);
@ -1413,12 +1413,12 @@ void console_handler::do_droid()
if(side < 1 || side > menu_handler_.teams().size()) {
utils::string_map symbols;
symbols["side"] = side_s;
command_failed(vgettext("Can't droid invalid side: '$side'.", symbols));
command_failed(VGETTEXT("Can't droid invalid side: '$side'.", symbols));
return;
} else if(menu_handler_.board().get_team(side).is_network()) {
utils::string_map symbols;
symbols["side"] = std::to_string(side);
command_failed(vgettext("Can't droid networked side: '$side'.", symbols));
command_failed(VGETTEXT("Can't droid networked side: '$side'.", symbols));
return;
} else if(menu_handler_.board().get_team(side).is_local_human()) {
if(menu_handler_.board().get_team(side).is_droid() ? action == " on" : action == " off") {
@ -1436,7 +1436,7 @@ void console_handler::do_droid()
utils::string_map symbols;
symbols["side"] = side_s;
command_failed(vgettext("Can't droid a local ai side: '$side'.", symbols));
command_failed(VGETTEXT("Can't droid a local ai side: '$side'.", symbols));
}
menu_handler_.textbox_info_.close(*menu_handler_.gui_);
}
@ -1452,17 +1452,17 @@ void console_handler::do_idle()
if(side < 1 || side > menu_handler_.teams().size()) {
utils::string_map symbols;
symbols["side"] = side_s;
command_failed(vgettext("Can't idle invalid side: '$side'.", symbols));
command_failed(VGETTEXT("Can't idle invalid side: '$side'.", symbols));
return;
} else if(menu_handler_.board().get_team(side).is_network()) {
utils::string_map symbols;
symbols["side"] = std::to_string(side);
command_failed(vgettext("Can't idle networked side: '$side'.", symbols));
command_failed(VGETTEXT("Can't idle networked side: '$side'.", symbols));
return;
} else if(menu_handler_.board().get_team(side).is_local_ai()) {
utils::string_map symbols;
symbols["side"] = std::to_string(side);
command_failed(vgettext("Can't idle local ai side: '$side'.", symbols));
command_failed(VGETTEXT("Can't idle local ai side: '$side'.", symbols));
return;
} else if(menu_handler_.board().get_team(side).is_local_human()) {
if(menu_handler_.board().get_team(side).is_idle() ? action == " on" : action == " off") {
@ -1522,7 +1522,7 @@ void console_handler::do_control()
if(it_t == resources::gameboard->teams().end()) {
utils::string_map symbols;
symbols["side"] = side;
command_failed(vgettext("Can't change control of invalid side: '$side'.", symbols));
command_failed(VGETTEXT("Can't change control of invalid side: '$side'.", symbols));
return;
} else {
side_num = it_t->side();
@ -1532,7 +1532,7 @@ void console_handler::do_control()
if(side_num < 1 || side_num > menu_handler_.teams().size()) {
utils::string_map symbols;
symbols["side"] = side;
command_failed(vgettext("Can't change control of out-of-bounds side: '$side'.", symbols));
command_failed(VGETTEXT("Can't change control of out-of-bounds side: '$side'.", symbols));
return;
}
@ -1549,14 +1549,14 @@ void console_handler::do_controller()
} catch(bad_lexical_cast&) {
utils::string_map symbols;
symbols["side"] = side;
command_failed(vgettext("Can't query control of invalid side: '$side'.", symbols));
command_failed(VGETTEXT("Can't query control of invalid side: '$side'.", symbols));
return;
}
if(side_num < 1 || side_num > menu_handler_.teams().size()) {
utils::string_map symbols;
symbols["side"] = side;
command_failed(vgettext("Can't query control of out-of-bounds side: '$side'.", symbols));
command_failed(VGETTEXT("Can't query control of out-of-bounds side: '$side'.", symbols));
return;
}

View file

@ -167,7 +167,7 @@ void turn_changed(const std::string & player_name)
if (notif_pref(id)) {
utils::string_map player;
player["name"] = player_name;
desktop::notifications::send(_("Turn changed"), vgettext("$name has taken control", player), desktop::notifications::TURN_CHANGED);
desktop::notifications::send(_("Turn changed"), VGETTEXT("$name has taken control", player), desktop::notifications::TURN_CHANGED);
}
}

View file

@ -18,7 +18,7 @@
#include "chat_events.hpp" // for chat_handler, etc
#include "config.hpp" // for config, etc
#include "display_chat_manager.hpp" // for add_chat_message, add_observer, etc
#include "formula/string_utils.hpp" // for vgettext
#include "formula/string_utils.hpp" // for VGETTEXT
#include "game_board.hpp" // for game_board
#include "game_display.hpp" // for game_display
#include "game_end_exceptions.hpp" // for end_level_exception, etc
@ -259,7 +259,7 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
//if you want that) and not ai or empty and if it is not the dropping side itself,
//get this team in as well
t_vars["player"] = t->current_player();
options.emplace_back(vgettext("Give control to their ally $player", t_vars));
options.emplace_back(VGETTEXT("Give control to their ally $player", t_vars));
control_change_options++;
}
@ -268,7 +268,7 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
//get all observers in as options to transfer control
for (const std::string &screen_observers : game_display::get_singleton()->observers()) {
t_vars["player"] = screen_observers;
options.emplace_back(vgettext("Give control to observer $player", t_vars));
options.emplace_back(VGETTEXT("Give control to observer $player", t_vars));
observers.push_back(screen_observers);
control_change_options++;
}
@ -279,7 +279,7 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
options.emplace_back(_("Save and abort game"));
t_vars["player"] = tm.current_player();
const std::string gettext_message = vgettext("$player has left the game. What do you want to do?", t_vars);
const std::string gettext_message = VGETTEXT("$player has left the game. What do you want to do?", t_vars);
gui2::dialogs::simple_item_selector dlg("", gettext_message, options);
dlg.set_single_button(true);
dlg.show();

View file

@ -162,7 +162,7 @@ void show_wesnothd_server_search()
!old_path.empty() && filesystem::is_directory(old_path)
? old_path : filesystem::get_exe_dir();
const std::string msg = vgettext(
const std::string msg = VGETTEXT(
"The <b>$filename</b> server application provides multiplayer server functionality and is required for hosting local network games. It will normally be found in the same folder as the game executable.", {{"filename", filename}});
gui2::dialogs::file_dialog dlg;

View file

@ -393,7 +393,7 @@ namespace
symbols["player"] = resources::controller->current_team().current_player();
display::announce_options announce_options;
announce_options.lifetime = 250;
display::get_singleton()->announce(vgettext(message, symbols), font::NORMAL_COLOR, announce_options);
display::get_singleton()->announce(VGETTEXT(message, symbols), font::NORMAL_COLOR, announce_options);
}
}
SYNCED_COMMAND_HANDLER_FUNCTION(debug_unit, child, use_undo, /*show*/, /*error_handler*/)

View file

@ -323,7 +323,7 @@ void user_choice_manager::update_local_choice()
}
}
}
wait_message_ = vgettext("waiting for $desc from side(s) $sides", {std::make_pair("desc", uch_.description()), std::make_pair("sides", sides_str)});
wait_message_ = VGETTEXT("waiting for $desc from side(s) $sides", {std::make_pair("desc", uch_.description()), std::make_pair("sides", sides_str)});
if(local_choice_prev != local_choice_) {
changed_event_.notify_observers();
}

View file

@ -23,7 +23,7 @@
#include "deprecation.hpp"
#include "display_context.hpp"
#include "formatter.hpp"
#include "formula/string_utils.hpp" // for vgettext
#include "formula/string_utils.hpp" // for VGETTEXT
#include "game_board.hpp" // for game_board
#include "game_config.hpp" // for add_color_info, etc
#include "game_data.hpp"
@ -1782,13 +1782,12 @@ std::string unit::describe_builtin_effect(std::string apply_to, const config& ef
utils::string_map symbols;
symbols["attack_list"] = utils::format_conjunct_list("", attack_names);
symbols["effect_description"] = desc;
return vgettext("$attack_list|: $effect_description", symbols);
return VGETTEXT("$attack_list|: $effect_description", symbols);
}
} else if(apply_to == "hitpoints") {
const std::string& increase_total = effect["increase_total"];
if(!increase_total.empty()) {
return vgettext(
"wesnoth",
return VGETTEXT(
"<span color=\"$color\">$number_or_percent</span> HP",
{{"number_or_percent", utils::print_modifier(increase_total)}, {"color", increase_total[0] == '-' ? "red" : "green"}});
}
@ -1804,16 +1803,16 @@ std::string unit::describe_builtin_effect(std::string apply_to, const config& ef
std::stoi(increase),
{{"number_or_percent", utils::print_modifier(increase)}, {"color", increase[0] == '-' ? "red" : "green"}});
} else if(apply_to == "vision") {
return vgettext(
return VGETTEXT(
"<span color=\"$color\">$number_or_percent</span> vision",
{{"number_or_percent", utils::print_modifier(increase)}, {"color", increase[0] == '-' ? "red" : "green"}});
} else if(apply_to == "jamming") {
return vgettext(
return VGETTEXT(
"<span color=\"$color\">$number_or_percent</span> jamming",
{{"number_or_percent", utils::print_modifier(increase)}, {"color", increase[0] == '-' ? "red" : "green"}});
} else if(apply_to == "max_experience") {
// Unlike others, decreasing experience is a *GOOD* thing
return vgettext(
return VGETTEXT(
"<span color=\"$color\">$number_or_percent</span> XP to advance",
{{"number_or_percent", utils::print_modifier(increase)}, {"color", increase[0] == '-' ? "green" : "red"}});
} else if(apply_to == "max_attacks") {
@ -1824,7 +1823,7 @@ std::string unit::describe_builtin_effect(std::string apply_to, const config& ef
{{"number_or_percent", utils::print_modifier(increase)}, {"color", increase[0] == '-' ? "red" : "green"}});
} else if(apply_to == "recall_cost") {
// Unlike others, decreasing recall cost is a *GOOD* thing
return vgettext(
return VGETTEXT(
"<span color=\"$color\">$number_or_percent</span> cost to recall",
{{"number_or_percent", utils::print_modifier(increase)}, {"color", increase[0] == '-' ? "green" : "red"}});
}
@ -2230,7 +2229,7 @@ void unit::add_modification(const std::string& mod_type, const config& mod, bool
}
if(effect["times"] == "per level" && !times) {
description = vgettext("$effect_description per level", {{"effect_description", description}});
description = VGETTEXT("$effect_description per level", {{"effect_description", description}});
}
if(!description.empty()) {

View file

@ -1106,9 +1106,9 @@ void manager::options_dlg()
t_vars["player"] = t.current_player();
std::size_t t_index = t.side()-1;
if(team_plans_hidden_[t_index])
options.emplace_back(vgettext("Show plans for $player", t_vars));
options.emplace_back(VGETTEXT("Show plans for $player", t_vars));
else
options.emplace_back(vgettext("Hide plans for $player", t_vars));
options.emplace_back(VGETTEXT("Hide plans for $player", t_vars));
}
gui2::dialogs::simple_item_selector dlg("", _("Whiteboard Options"), options);

View file

@ -91,10 +91,10 @@ std::string missing_mandatory_wml_key(
symbols["primary_key"] = primary_key;
symbols["primary_value"] = primary_value;
return vgettext("In section '[$section|]' where '$primary_key| = "
return VGETTEXT("In section '[$section|]' where '$primary_key| = "
"$primary_value' the mandatory key '$key|' isn't set.", symbols);
} else {
return vgettext("In section '[$section|]' the "
return VGETTEXT("In section '[$section|]' the "
"mandatory key '$key|' isn't set.", symbols);
}
}
@ -110,7 +110,7 @@ std::string deprecate_wml_key_warning(
symbols["key"] = key;
symbols["removal_version"] = removal_version;
return vgettext("The key '$key' is deprecated and support "
return VGETTEXT("The key '$key' is deprecated and support "
"will be removed in version $removal_version.", symbols);
}
@ -128,7 +128,7 @@ std::string deprecated_renamed_wml_key_warning(
symbols["key"] = key;
symbols["removal_version"] = removal_version;
return vgettext(
return VGETTEXT(
"The key '$deprecated_key' has been renamed to '$key'. "
"Support for '$deprecated_key' will be removed in version "
"$removal_version."