Additional localization fixes (#966)

This commit is contained in:
Francesco Saltori 2023-09-14 12:47:59 +02:00 committed by GitHub
parent c66ab0c51a
commit 96800c6f97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 68 additions and 123 deletions

View File

@ -29,8 +29,8 @@ jobs:
- name: "Generate POT file using xgettext"
run: >
find src -name *.cpp -o -name *.hpp -o -name *.h |
xargs xgettext --from-code=utf-8
-k_ -kwxTRANSLATE -w 100
xargs xgettext --from-code=utf-8 -w 100
--keyword="_" --keyword="wxTRANSLATE" --keyword="wxPLURAL:1,2"
--check=space-ellipsis --omit-header
-o cemu.pot

View File

@ -424,7 +424,7 @@ bool DownloadManager::syncAccountTickets()
bool DownloadManager::syncSystemTitleTickets()
{
setStatusMessage(std::string(_("Downloading system tickets...")), DLMGR_STATUS_CODE::CONNECTING);
setStatusMessage(_("Downloading system tickets...").utf8_string(), DLMGR_STATUS_CODE::CONNECTING);
// todo - add GetAuth() function
NAPI::AuthInfo authInfo;
authInfo.accountId = m_authInfo.nnidAccountName;
@ -486,7 +486,7 @@ bool DownloadManager::syncSystemTitleTickets()
// build list of updates for which either an installed game exists or the base title ticket is cached
bool DownloadManager::syncUpdateTickets()
{
setStatusMessage(std::string(_("Retrieving update information...")), DLMGR_STATUS_CODE::CONNECTING);
setStatusMessage(_("Retrieving update information...").utf8_string(), DLMGR_STATUS_CODE::CONNECTING);
// download update version list
downloadTitleVersionList();
if (!m_hasTitleVersionList)
@ -566,7 +566,7 @@ bool DownloadManager::syncTicketCache()
setStatusMessage(msg, DLMGR_STATUS_CODE::CONNECTING);
prepareIDBE(ticketInfo.titleId);
}
setStatusMessage(std::string(_("Connected. Right click entries in the list to start downloading")), DLMGR_STATUS_CODE::CONNECTED);
setStatusMessage(_("Connected. Right click entries in the list to start downloading").utf8_string(), DLMGR_STATUS_CODE::CONNECTED);
return true;
}
@ -652,7 +652,7 @@ void DownloadManager::_handle_connect()
// reset login state
m_iasToken.serviceAccountId.clear();
m_iasToken.deviceToken.clear();
setStatusMessage(std::string(_("Logging in..")), DLMGR_STATUS_CODE::CONNECTING);
setStatusMessage(_("Logging in...").utf8_string(), DLMGR_STATUS_CODE::CONNECTING);
// retrieve ECS AccountId + DeviceToken from cache
if (s_nupFileCache)
{
@ -675,7 +675,7 @@ void DownloadManager::_handle_connect()
cemuLog_log(LogType::Force, "Failed to request IAS token");
cemu_assert_debug(false);
m_connectState.store(CONNECT_STATE::FAILED);
setStatusMessage(std::string(_("Login failed. Outdated or incomplete online files?")), DLMGR_STATUS_CODE::FAILED);
setStatusMessage(_("Login failed. Outdated or incomplete online files?").utf8_string(), DLMGR_STATUS_CODE::FAILED);
return;
}
}
@ -683,16 +683,16 @@ void DownloadManager::_handle_connect()
if (!_connect_queryAccountStatusAndServiceURLs())
{
m_connectState.store(CONNECT_STATE::FAILED);
setStatusMessage(std::string(_("Failed to query account status. Invalid account information?")), DLMGR_STATUS_CODE::FAILED);
setStatusMessage(_("Failed to query account status. Invalid account information?").utf8_string(), DLMGR_STATUS_CODE::FAILED);
return;
}
// load ticket cache and sync
setStatusMessage(std::string(_("Updating ticket cache")), DLMGR_STATUS_CODE::CONNECTING);
setStatusMessage(_("Updating ticket cache").utf8_string(), DLMGR_STATUS_CODE::CONNECTING);
loadTicketCache();
if (!syncTicketCache())
{
m_connectState.store(CONNECT_STATE::FAILED);
setStatusMessage(std::string(_("Failed to request tickets (invalid NNID?)")), DLMGR_STATUS_CODE::FAILED);
setStatusMessage(_("Failed to request tickets (invalid NNID?)").utf8_string(), DLMGR_STATUS_CODE::FAILED);
return;
}
searchForIncompleteDownloads();
@ -716,7 +716,7 @@ void DownloadManager::connect(
if (nnidAccountName.empty())
{
m_connectState.store(CONNECT_STATE::FAILED);
setStatusMessage(std::string(_("This account is not linked with an NNID")), DLMGR_STATUS_CODE::FAILED);
setStatusMessage(_("This account is not linked with an NNID").utf8_string(), DLMGR_STATUS_CODE::FAILED);
return;
}
runManager();
@ -726,7 +726,7 @@ void DownloadManager::connect(
{
cemuLog_log(LogType::Force, "DLMgr: Invalid password hash");
m_connectState.store(CONNECT_STATE::FAILED);
setStatusMessage(std::string(_("Failed. Account does not have password set")), DLMGR_STATUS_CODE::FAILED);
setStatusMessage(_("Failed. Account does not have password set").utf8_string(), DLMGR_STATUS_CODE::FAILED);
return;
}
m_authInfo.region = region;

View File

@ -169,7 +169,7 @@ bool CemuApp::OnInit()
"Thank you for testing the in-development build of Cemu for macOS.\n \n"
"The macOS port is currently purely experimental and should not be considered stable or ready for issue-free gameplay. "
"There are also known issues with degraded performance due to the use of MoltenVk and Rosetta for ARM Macs. We appreciate your patience while we improve Cemu for macOS.");
wxMessageDialog dialog(nullptr, message, "Preview version", wxCENTRE | wxOK | wxICON_WARNING);
wxMessageDialog dialog(nullptr, message, _("Preview version"), wxCENTRE | wxOK | wxICON_WARNING);
dialog.SetOKLabel(_("I understand"));
dialog.ShowModal();
GetConfig().did_show_macos_disclaimer = true;

View File

@ -166,7 +166,7 @@ GameProfileWindow::GameProfileWindow(wxWindow* parent, uint64_t title_id)
for (int i = 0; i < 8; ++i)
{
profile_sizer->Add(new wxStaticText(panel, wxID_ANY, fmt::format("{} {}", _("Controller").utf8_string(), (i + 1))), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
profile_sizer->Add(new wxStaticText(panel, wxID_ANY, formatWxString(_("Controller {}"), i + 1)), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
m_controller_profile[i] = new wxComboBox(panel, wxID_ANY,"", wxDefaultPosition, wxDefaultSize, 0, nullptr, wxCB_DROPDOWN| wxCB_READONLY);
m_controller_profile[i]->SetMinSize(wxSize(250, -1));
@ -244,7 +244,7 @@ void GameProfileWindow::SetProfileInt(gameProfileIntegerOption_t& option, wxChec
void GameProfileWindow::ApplyProfile()
{
if(m_game_profile.m_gameName)
this->SetTitle(fmt::format("{} - {}", _("Edit game profile").utf8_string(), m_game_profile.m_gameName.value()));
this->SetTitle(_("Edit game profile") + " - " + m_game_profile.m_gameName.value());
// general
m_load_libs->SetValue(m_game_profile.m_loadSharedLibraries.value());

View File

@ -10,24 +10,24 @@
#include "gui/helpers/wxHelpers.h"
#include "wxHelper.h"
std::string _GetTitleIdTypeStr(TitleId titleId)
wxString _GetTitleIdTypeStr(TitleId titleId)
{
TitleIdParser tip(titleId);
switch (tip.GetType())
{
case TitleIdParser::TITLE_TYPE::AOC:
return _("DLC").utf8_string();
return _("DLC");
case TitleIdParser::TITLE_TYPE::BASE_TITLE:
return _("Base game").utf8_string();
return _("Base game");
case TitleIdParser::TITLE_TYPE::BASE_TITLE_DEMO:
return _("Demo").utf8_string();
return _("Demo");
case TitleIdParser::TITLE_TYPE::SYSTEM_TITLE:
case TitleIdParser::TITLE_TYPE::SYSTEM_OVERLAY_TITLE:
return _("System title").utf8_string();
return _("System title");
case TitleIdParser::TITLE_TYPE::SYSTEM_DATA:
return _("System data title").utf8_string();
return _("System data title");
case TitleIdParser::TITLE_TYPE::BASE_TITLE_UPDATE:
return _("Update").utf8_string();
return _("Update");
default:
break;
}
@ -57,8 +57,8 @@ bool GameUpdateWindow::ParseUpdate(const fs::path& metaPath)
if (tip.GetType() != tipOther.GetType())
{
std::string typeStrToInstall = _GetTitleIdTypeStr(m_title_info.GetAppTitleId());
std::string typeStrCurrentlyInstalled = _GetTitleIdTypeStr(tmp.GetAppTitleId());
auto typeStrToInstall = _GetTitleIdTypeStr(m_title_info.GetAppTitleId());
auto typeStrCurrentlyInstalled = _GetTitleIdTypeStr(tmp.GetAppTitleId());
auto wxMsg = _("It seems that there is already a title installed at the target location but it has a different type.\nCurrently installed: \'{}\' Installing: \'{}\'\n\nThis can happen for titles which were installed with very old Cemu versions.\nDo you still want to continue with the installation? It will replace the currently installed title.");
wxMessageDialog dialog(this, formatWxString(wxMsg, typeStrCurrentlyInstalled, typeStrToInstall), _("Warning"), wxCENTRE | wxYES_NO | wxICON_EXCLAMATION);
@ -131,8 +131,8 @@ bool GameUpdateWindow::ParseUpdate(const fs::path& metaPath)
const fs::space_info targetSpace = fs::space(ActiveSettings::GetMlcPath());
if (targetSpace.free <= m_required_size)
{
auto string = wxStringFormat(_("Not enough space available.\nRequired: {0} MB\nAvailable: {1} MB"), L"%lld %lld", (m_required_size / 1024 / 1024), (targetSpace.free / 1024 / 1024));
throw std::runtime_error(string);
auto string = formatWxString(_("Not enough space available.\nRequired: {0} MB\nAvailable: {1} MB"), (m_required_size / 1024 / 1024), (targetSpace.free / 1024 / 1024));
throw std::runtime_error(string.utf8_string());
}
return true;

View File

@ -2043,17 +2043,17 @@ void GeneralSettings2::OnShowOnlineValidator(wxCommandEvent& event)
wxMessageBox(err, _("Online Status"), wxOK | wxCENTRE | wxICON_INFORMATION);
}
std::string GeneralSettings2::GetOnlineAccountErrorMessage(OnlineAccountError error)
wxString GeneralSettings2::GetOnlineAccountErrorMessage(OnlineAccountError error)
{
switch (error) {
case OnlineAccountError::kNoAccountId:
return _("AccountId missing (The account is not connected to a NNID)").utf8_string();
return _("AccountId missing (The account is not connected to a NNID)");
case OnlineAccountError::kNoPasswordCached:
return _("IsPasswordCacheEnabled is set to false (The remember password option on your Wii U must be enabled for this account before dumping it)").utf8_string();
return _("IsPasswordCacheEnabled is set to false (The remember password option on your Wii U must be enabled for this account before dumping it)");
case OnlineAccountError::kPasswordCacheEmpty:
return _("AccountPasswordCache is empty (The remember password option on your Wii U must be enabled for this account before dumping it)").utf8_string();
return _("AccountPasswordCache is empty (The remember password option on your Wii U must be enabled for this account before dumping it)");
case OnlineAccountError::kNoPrincipalId:
return _("PrincipalId missing").utf8_string();
return _("PrincipalId missing");
default:
return "no error";
}

View File

@ -101,7 +101,7 @@ private:
void OnShowOnlineValidator(wxCommandEvent& event);
void OnOnlineEnable(wxCommandEvent& event);
void OnAccountServiceChanged(wxCommandEvent& event);
std::string GetOnlineAccountErrorMessage(OnlineAccountError error);
static wxString GetOnlineAccountErrorMessage(OnlineAccountError error);
// updates cemu audio devices
void UpdateAudioDevice();

View File

@ -445,7 +445,7 @@ void GraphicPacksWindow2::OnTreeSelectionChanged(wxTreeEvent& event)
m_graphic_pack_name->SetLabel(wxHelper::FromUtf8(m_gp_name));
if (gp->GetDescription().empty())
m_gp_description = _("This graphic pack has no description");
m_gp_description = _("This graphic pack has no description").utf8_string();
else
m_gp_description = gp->GetDescription();
@ -609,7 +609,7 @@ void GraphicPacksWindow2::OnCheckForUpdates(wxCommandEvent& event)
// check if enabled graphic packs are lost:
const auto& new_packs = GraphicPack2::GetGraphicPacks();
std::stringstream str;
std::stringstream lost_packs;
for(const auto& p : old_packs)
{
if (!p->IsEnabled())
@ -622,15 +622,16 @@ void GraphicPacksWindow2::OnCheckForUpdates(wxCommandEvent& event)
if(it == new_packs.cend())
{
str << p->GetPath() << std::endl;
lost_packs << p->GetPath() << "\n";
}
}
const auto packs = str.str();
if(!packs.empty())
const auto lost_packs_str = lost_packs.str();
if (!lost_packs_str.empty())
{
wxMessageBox(fmt::format("{}\n \n{} \n{}", _("This update removed or renamed the following graphic packs:").utf8_string(), packs, _("You may need to set them up again.").utf8_string()),
_("Warning"), wxOK | wxCENTRE | wxICON_INFORMATION, this);
wxString message = _("This update removed or renamed the following graphic packs:");
message << "\n \n" << lost_packs_str << " \n" << _("You may need to set them up again.");
wxMessageBox(message, _("Warning"), wxOK | wxCENTRE | wxICON_INFORMATION, this);
}
}
}

View File

@ -472,9 +472,7 @@ bool MemorySearcherTool::VerifySearchValue() const
void MemorySearcherTool::FillResultList()
{
//char text[128];
//sprintf(text, "Results (%u)", (uint32)m_searchBuffer.size());
auto text = wxStringFormat(_("Results ({0})"), L"%llu", m_searchBuffer.size());
auto text = formatWxString(_("Results ({0})"), m_searchBuffer.size());
m_textEntryTable->SetLabelText(text);
m_listResults->DeleteAllItems();

View File

@ -799,7 +799,7 @@ void TitleManager::SetConnected(bool state)
void TitleManager::Callback_ConnectStatusUpdate(std::string statusText, DLMGR_STATUS_CODE statusCode)
{
TitleManager* titleManager = static_cast<TitleManager*>(DownloadManager::GetInstance()->getUserData());
titleManager->SetDownloadStatusText(statusText);
titleManager->SetDownloadStatusText(wxString::FromUTF8(statusText));
if (statusCode == DLMGR_STATUS_CODE::FAILED)
{
auto* evt = new wxCommandEvent(wxEVT_DL_DISCONNECT_COMPLETE);

View File

@ -501,16 +501,16 @@ wxString wxDownloadManagerList::GetTitleEntryText(const TitleEntry& entry, ItemC
return wxEmptyString;
}
std::string wxDownloadManagerList::GetTranslatedTitleEntryType(EntryType type)
wxString wxDownloadManagerList::GetTranslatedTitleEntryType(EntryType type)
{
switch (type)
{
case EntryType::Base:
return _("base").utf8_string();
return _("base");
case EntryType::Update:
return _("update").utf8_string();
return _("update");
case EntryType::DLC:
return _("DLC").utf8_string();
return _("DLC");
default:
return std::to_string(static_cast<std::underlying_type_t<EntryType>>(type));
}

View File

@ -150,6 +150,6 @@ private:
bool SortFunc(std::span<int> sortColumnOrder, const Type_t& v1, const Type_t& v2);
static wxString GetTitleEntryText(const TitleEntry& entry, ItemColumn column);
static std::string GetTranslatedTitleEntryType(EntryType entryType);
static wxString GetTranslatedTitleEntryType(EntryType entryType);
std::future<bool> m_context_worker;
};

View File

@ -1009,15 +1009,20 @@ void wxGameList::OnGameEntryUpdatedByTitleId(wxTitleIdEvent& event)
if (iosu::pdm::GetStatForGamelist(baseTitleId, playTimeStat))
{
// time played
uint32 timePlayed = playTimeStat.numMinutesPlayed * 60;
if (timePlayed == 0)
uint32 minutesPlayed = playTimeStat.numMinutesPlayed;
if (minutesPlayed == 0)
SetItem(index, ColumnGameTime, wxEmptyString);
else if (timePlayed < 60)
SetItem(index, ColumnGameTime, fmt::format("{} seconds", timePlayed));
else if (timePlayed < 60 * 60)
SetItem(index, ColumnGameTime, fmt::format("{} minutes", timePlayed / 60));
else if (minutesPlayed < 60)
SetItem(index, ColumnGameTime, formatWxString(wxPLURAL("{} minute", "{} minutes", minutesPlayed), minutesPlayed));
else
SetItem(index, ColumnGameTime, fmt::format("{} hours {} minutes", timePlayed / 3600, (timePlayed / 60) % 60));
{
uint32 hours = minutesPlayed / 60;
uint32 minutes = minutesPlayed % 60;
wxString hoursText = formatWxString(wxPLURAL("{} hour", "{} hours", hours), hours);
wxString minutesText = formatWxString(wxPLURAL("{} minute", "{} minutes", minutes), minutes);
SetItem(index, ColumnGameTime, hoursText + " " + minutesText);
}
// last played
if (playTimeStat.last_played.year != 0)
{

View File

@ -963,20 +963,20 @@ wxString wxTitleManagerList::GetTitleEntryText(const TitleEntry& entry, ItemColu
return wxEmptyString;
}
std::string wxTitleManagerList::GetTranslatedTitleEntryType(EntryType type)
wxString wxTitleManagerList::GetTranslatedTitleEntryType(EntryType type)
{
switch (type)
{
case EntryType::Base:
return _("base").utf8_string();
return _("base");
case EntryType::Update:
return _("update").utf8_string();
return _("update");
case EntryType::Dlc:
return _("DLC").utf8_string();
return _("DLC");
case EntryType::Save:
return _("save").utf8_string();
return _("save");
case EntryType::System:
return _("system").utf8_string();
return _("system");
default:
return std::to_string(static_cast<std::underlying_type_t<EntryType>>(type));
}

View File

@ -132,7 +132,7 @@ private:
bool SortFunc(int column, const Type_t& v1, const Type_t& v2);
static wxString GetTitleEntryText(const TitleEntry& entry, ItemColumn column);
static std::string GetTranslatedTitleEntryType(EntryType entryType);
static wxString GetTranslatedTitleEntryType(EntryType entryType);
std::future<bool> m_context_worker;
uint64 m_callbackIdTitleList;

View File

@ -1,5 +1,7 @@
#pragma once
#define wxNO_UNSAFE_WXSTRING_CONV 1
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
@ -36,67 +38,6 @@
extern bool g_inputConfigWindowHasFocus;
// wx helper functions
#include <wx/string.h>
struct wxStringFormatParameters
{
sint32 parameter_index;
sint32 parameter_count;
wchar_t* token_buffer;
wchar_t* substitude_parameter;
};
template <typename ...Args>
wxString wxStringFormat(std::wstring& format, wxStringFormatParameters& parameters)
{
return format;
}
template <typename T, typename ...Args>
wxString wxStringFormat(std::wstring& format, wxStringFormatParameters& parameters, T arg, Args... args)
{
wchar_t tmp[64];
swprintf(tmp, 64, LR"(\{[%d]+\})", parameters.parameter_index);
const std::wregex placeholder_regex(tmp);
auto result = format;
while (std::regex_search(result, placeholder_regex))
{
result = std::regex_replace(result, placeholder_regex, parameters.substitude_parameter, std::regex_constants::format_first_only);
result = wxString::Format(wxString(result), arg);
}
parameters.parameter_index++;
if (parameters.parameter_index == parameters.parameter_count)
return result;
parameters.substitude_parameter = std::wcstok(nullptr, LR"( )", &parameters.token_buffer);
return wxStringFormat(result, parameters, args...);
}
template <typename ...T>
wxString wxStringFormat(const wxString& format, const wchar_t* parameters, T... args)
{
const auto parameter_count = std::count(parameters, parameters + wcslen(parameters), '%');
if (parameter_count == 0)
return format;
const auto copy = wcsdup(parameters);
wxStringFormatParameters para;
para.substitude_parameter = std::wcstok(copy, LR"( )", &para.token_buffer);
para.parameter_count = parameter_count;
para.parameter_index = 0;
auto tmp_string = format.ToStdWstring();
auto result = wxStringFormat(tmp_string, para, args...);
free(copy);
return result;
}
inline bool SendSliderEvent(wxSlider* slider, int new_value)
{
wxCommandEvent cevent(wxEVT_SLIDER, slider->GetId());