Host: Add disambiguation variants for translations
This commit is contained in:
@ -210,10 +210,10 @@ static constexpr const std::array s_backend_names = {
|
||||
#endif
|
||||
};
|
||||
static constexpr const std::array s_backend_display_names = {
|
||||
TRANSLATE_NOOP("AudioStream", "Null (No Output)"),
|
||||
TRANSLATE_DISAMBIG_NOOP("Settings", "Null (No Output)", "AudioBackend"),
|
||||
#ifndef __ANDROID__
|
||||
TRANSLATE_NOOP("AudioStream", "Cubeb"),
|
||||
TRANSLATE_NOOP("AudioStream", "SDL"),
|
||||
TRANSLATE_DISAMBIG_NOOP("Settings", "Cubeb", "AudioBackend"),
|
||||
TRANSLATE_DISAMBIG_NOOP("Settings", "SDL", "AudioBackend"),
|
||||
#else
|
||||
"AAudio",
|
||||
"OpenSL ES",
|
||||
@ -250,26 +250,28 @@ static constexpr const std::array s_stretch_mode_names = {
|
||||
"TimeStretch",
|
||||
};
|
||||
static constexpr const std::array s_stretch_mode_display_names = {
|
||||
TRANSLATE_NOOP("AudioStream", "Off (Noisy)"),
|
||||
TRANSLATE_NOOP("AudioStream", "Resampling (Pitch Shift)"),
|
||||
TRANSLATE_NOOP("AudioStream", "Time Stretch (Tempo Change, Best Sound)"),
|
||||
TRANSLATE_DISAMBIG_NOOP("Settings", "Off (Noisy)", "AudioStretchMode"),
|
||||
TRANSLATE_DISAMBIG_NOOP("Settings", "Resampling (Pitch Shift)", "AudioStretchMode"),
|
||||
TRANSLATE_DISAMBIG_NOOP("Settings", "Time Stretch (Tempo Change, Best Sound)", "AudioStretchMode"),
|
||||
};
|
||||
|
||||
const char* AudioStream::GetStretchModeName(AudioStretchMode mode)
|
||||
{
|
||||
return (static_cast<u32>(mode) < s_stretch_mode_names.size()) ? s_stretch_mode_names[static_cast<u32>(mode)] : "";
|
||||
return (static_cast<size_t>(mode) < s_stretch_mode_names.size()) ? s_stretch_mode_names[static_cast<size_t>(mode)] :
|
||||
"";
|
||||
}
|
||||
|
||||
const char* AudioStream::GetStretchModeDisplayName(AudioStretchMode mode)
|
||||
{
|
||||
return (static_cast<u32>(mode) < s_stretch_mode_display_names.size()) ?
|
||||
Host::TranslateToCString("AudioStream", s_stretch_mode_display_names[static_cast<u32>(mode)]) :
|
||||
return (static_cast<size_t>(mode) < s_stretch_mode_display_names.size()) ?
|
||||
Host::TranslateToCString("Settings", s_stretch_mode_display_names[static_cast<size_t>(mode)],
|
||||
"AudioStretchMode") :
|
||||
"";
|
||||
}
|
||||
|
||||
std::optional<AudioStretchMode> AudioStream::ParseStretchMode(const char* name)
|
||||
{
|
||||
for (u8 i = 0; i < static_cast<u8>(AudioStretchMode::Count); i++)
|
||||
for (size_t i = 0; i < static_cast<u8>(AudioStretchMode::Count); i++)
|
||||
{
|
||||
if (std::strcmp(name, s_stretch_mode_names[i]) == 0)
|
||||
return static_cast<AudioStretchMode>(i);
|
||||
|
||||
@ -14,7 +14,8 @@
|
||||
Log_SetChannel(Host);
|
||||
|
||||
namespace Host {
|
||||
static std::pair<const char*, u32> LookupTranslationString(std::string_view context, std::string_view msg);
|
||||
static std::pair<const char*, u32> LookupTranslationString(std::string_view context, std::string_view msg,
|
||||
std::string_view disambiguation);
|
||||
|
||||
static constexpr u32 TRANSLATION_STRING_CACHE_SIZE = 4 * 1024 * 1024;
|
||||
using TranslationStringMap = PreferUnorderedStringMap<std::pair<u32, u32>>;
|
||||
@ -25,13 +26,15 @@ static std::vector<char> s_translation_string_cache;
|
||||
static u32 s_translation_string_cache_pos;
|
||||
} // namespace Host
|
||||
|
||||
std::pair<const char*, u32> Host::LookupTranslationString(std::string_view context, std::string_view msg)
|
||||
std::pair<const char*, u32> Host::LookupTranslationString(std::string_view context, std::string_view msg,
|
||||
std::string_view disambiguation)
|
||||
{
|
||||
// TODO: TranslatableString, compile-time hashing.
|
||||
|
||||
TranslationStringContextMap::iterator ctx_it;
|
||||
TranslationStringMap::iterator msg_it;
|
||||
std::pair<const char*, u32> ret;
|
||||
SmallString disambiguation_key;
|
||||
s32 len;
|
||||
|
||||
// Shouldn't happen, but just in case someone tries to translate an empty string.
|
||||
@ -42,13 +45,19 @@ std::pair<const char*, u32> Host::LookupTranslationString(std::string_view conte
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!disambiguation.empty())
|
||||
{
|
||||
disambiguation_key.append(disambiguation);
|
||||
disambiguation_key.append(msg);
|
||||
}
|
||||
|
||||
s_translation_string_mutex.lock_shared();
|
||||
ctx_it = s_translation_string_map.find(context);
|
||||
|
||||
if (ctx_it == s_translation_string_map.end()) [[unlikely]]
|
||||
goto add_string;
|
||||
|
||||
msg_it = ctx_it->second.find(msg);
|
||||
msg_it = ctx_it->second.find(disambiguation.empty() ? msg : disambiguation_key.view());
|
||||
if (msg_it == ctx_it->second.end()) [[unlikely]]
|
||||
goto add_string;
|
||||
|
||||
@ -69,15 +78,15 @@ add_string:
|
||||
s_translation_string_cache_pos = 0;
|
||||
}
|
||||
|
||||
if ((len =
|
||||
Internal::GetTranslatedStringImpl(context, msg, &s_translation_string_cache[s_translation_string_cache_pos],
|
||||
TRANSLATION_STRING_CACHE_SIZE - 1 - s_translation_string_cache_pos)) < 0)
|
||||
if ((len = Internal::GetTranslatedStringImpl(context, msg, disambiguation,
|
||||
&s_translation_string_cache[s_translation_string_cache_pos],
|
||||
TRANSLATION_STRING_CACHE_SIZE - 1 - s_translation_string_cache_pos)) < 0)
|
||||
{
|
||||
ERROR_LOG("WARNING: Clearing translation string cache, it might need to be larger.");
|
||||
s_translation_string_cache_pos = 0;
|
||||
if ((len =
|
||||
Internal::GetTranslatedStringImpl(context, msg, &s_translation_string_cache[s_translation_string_cache_pos],
|
||||
TRANSLATION_STRING_CACHE_SIZE - 1 - s_translation_string_cache_pos)) < 0)
|
||||
if ((len = Internal::GetTranslatedStringImpl(
|
||||
context, msg, disambiguation, &s_translation_string_cache[s_translation_string_cache_pos],
|
||||
TRANSLATION_STRING_CACHE_SIZE - 1 - s_translation_string_cache_pos)) < 0)
|
||||
{
|
||||
Panic("Failed to get translated string after clearing cache.");
|
||||
len = 0;
|
||||
@ -93,7 +102,8 @@ add_string:
|
||||
const u32 insert_pos = s_translation_string_cache_pos;
|
||||
s_translation_string_cache[insert_pos + static_cast<u32>(len)] = 0;
|
||||
|
||||
ctx_it->second.emplace(msg, std::pair<u32, u32>(insert_pos, static_cast<u32>(len)));
|
||||
ctx_it->second.emplace(disambiguation.empty() ? msg : disambiguation_key.view(),
|
||||
std::pair<u32, u32>(insert_pos, static_cast<u32>(len)));
|
||||
s_translation_string_cache_pos = insert_pos + static_cast<u32>(len) + 1;
|
||||
|
||||
ret.first = &s_translation_string_cache[insert_pos];
|
||||
@ -102,20 +112,21 @@ add_string:
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char* Host::TranslateToCString(std::string_view context, std::string_view msg)
|
||||
const char* Host::TranslateToCString(std::string_view context, std::string_view msg, std::string_view disambiguation)
|
||||
{
|
||||
return LookupTranslationString(context, msg).first;
|
||||
return LookupTranslationString(context, msg, disambiguation).first;
|
||||
}
|
||||
|
||||
std::string_view Host::TranslateToStringView(std::string_view context, std::string_view msg)
|
||||
std::string_view Host::TranslateToStringView(std::string_view context, std::string_view msg,
|
||||
std::string_view disambiguation)
|
||||
{
|
||||
const auto mp = LookupTranslationString(context, msg);
|
||||
const auto mp = LookupTranslationString(context, msg, disambiguation);
|
||||
return std::string_view(mp.first, mp.second);
|
||||
}
|
||||
|
||||
std::string Host::TranslateToString(std::string_view context, std::string_view msg)
|
||||
std::string Host::TranslateToString(std::string_view context, std::string_view msg, std::string_view disambiguation)
|
||||
{
|
||||
return std::string(TranslateToStringView(context, msg));
|
||||
return std::string(TranslateToStringView(context, msg, disambiguation));
|
||||
}
|
||||
|
||||
void Host::ClearTranslationCache()
|
||||
|
||||
@ -50,16 +50,17 @@ bool CopyTextToClipboard(std::string_view text);
|
||||
|
||||
/// Returns a localized version of the specified string within the specified context.
|
||||
/// The pointer is guaranteed to be valid until the next language change.
|
||||
const char* TranslateToCString(std::string_view context, std::string_view msg);
|
||||
const char* TranslateToCString(std::string_view context, std::string_view msg, std::string_view disambiguation = {});
|
||||
|
||||
/// Returns a localized version of the specified string within the specified context.
|
||||
/// The view is guaranteed to be valid until the next language change.
|
||||
/// NOTE: When passing this to fmt, positional arguments should be used in the base string, as
|
||||
/// not all locales follow the same word ordering.
|
||||
std::string_view TranslateToStringView(std::string_view context, std::string_view msg);
|
||||
std::string_view TranslateToStringView(std::string_view context, std::string_view msg,
|
||||
std::string_view disambiguation = {});
|
||||
|
||||
/// Returns a localized version of the specified string within the specified context.
|
||||
std::string TranslateToString(std::string_view context, std::string_view msg);
|
||||
std::string TranslateToString(std::string_view context, std::string_view msg, std::string_view disambiguation = {});
|
||||
|
||||
/// Returns a localized version of the specified string within the specified context, adjusting for plurals using %n.
|
||||
std::string TranslatePluralToString(const char* context, const char* msg, const char* disambiguation, int count);
|
||||
@ -70,7 +71,8 @@ void ClearTranslationCache();
|
||||
|
||||
namespace Internal {
|
||||
/// Implementation to retrieve a translated string.
|
||||
s32 GetTranslatedStringImpl(std::string_view context, std::string_view msg, char* tbuf, size_t tbuf_space);
|
||||
s32 GetTranslatedStringImpl(std::string_view context, std::string_view msg, std::string_view disambiguation, char* tbuf,
|
||||
size_t tbuf_space);
|
||||
} // namespace Internal
|
||||
} // namespace Host
|
||||
|
||||
@ -79,6 +81,11 @@ s32 GetTranslatedStringImpl(std::string_view context, std::string_view msg, char
|
||||
#define TRANSLATE_SV(context, msg) Host::TranslateToStringView(context, msg)
|
||||
#define TRANSLATE_STR(context, msg) Host::TranslateToString(context, msg)
|
||||
#define TRANSLATE_FS(context, msg) fmt::runtime(Host::TranslateToStringView(context, msg))
|
||||
#define TRANSLATE_DISAMBIG(context, msg, disambiguation) Host::TranslateToCString(context, msg, disambiguation)
|
||||
#define TRANSLATE_DISAMBIG_SV(context, msg, disambiguation) Host::TranslateToStringView(context, msg, disambiguation)
|
||||
#define TRANSLATE_DISAMBIG_STR(context, msg, disambiguation) Host::TranslateToString(context, msg, disambiguation)
|
||||
#define TRANSLATE_DISAMBIG_FS(context, msg, disambiguation) \
|
||||
fmt::runtime(Host::TranslateToStringView(context, msg, disambiguation))
|
||||
#define TRANSLATE_PLURAL_STR(context, msg, disambiguation, count) \
|
||||
Host::TranslatePluralToString(context, msg, disambiguation, count)
|
||||
#define TRANSLATE_PLURAL_SSTR(context, msg, disambiguation, count) \
|
||||
@ -88,3 +95,4 @@ s32 GetTranslatedStringImpl(std::string_view context, std::string_view msg, char
|
||||
|
||||
// Does not translate the string at runtime, but allows the UI to in its own way.
|
||||
#define TRANSLATE_NOOP(context, msg) msg
|
||||
#define TRANSLATE_DISAMBIG_NOOP(context, msg, disambiguation) msg
|
||||
|
||||
@ -2871,10 +2871,10 @@ static constexpr const std::array s_backend_names = {
|
||||
};
|
||||
static constexpr const std::array s_backend_display_names = {
|
||||
#ifdef _WIN32
|
||||
TRANSLATE_NOOP("MediaCapture", "Media Foundation"),
|
||||
TRANSLATE_DISAMBIG_NOOP("Settings", "Media Foundation", "MediaCaptureBackend"),
|
||||
#endif
|
||||
#ifndef __ANDROID__
|
||||
TRANSLATE_NOOP("MediaCapture", "FFmpeg"),
|
||||
TRANSLATE_DISAMBIG_NOOP("Settings", "FFmpeg", "MediaCaptureBackend"),
|
||||
#endif
|
||||
};
|
||||
static_assert(s_backend_names.size() == static_cast<size_t>(MediaCaptureBackend::MaxCount));
|
||||
@ -2903,7 +2903,8 @@ const char* MediaCapture::GetBackendName(MediaCaptureBackend backend)
|
||||
|
||||
const char* MediaCapture::GetBackendDisplayName(MediaCaptureBackend backend)
|
||||
{
|
||||
return Host::TranslateToCString("MediaCapture", s_backend_display_names[static_cast<size_t>(backend)]);
|
||||
return Host::TranslateToCString("Settings", s_backend_display_names[static_cast<size_t>(backend)],
|
||||
"MediaCaptureBackend");
|
||||
}
|
||||
|
||||
void MediaCapture::AdjustVideoSize(u32* width, u32* height)
|
||||
|
||||
Reference in New Issue
Block a user