mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2025-02-28 00:25:43 +00:00
Merge pull request #1792 from CookiePLMonster/plurality-pass
Plurality for non-Qt messages
This commit is contained in:
commit
4d2747fe74
|
@ -161,6 +161,11 @@ String::String(const char* Text) : m_pStringData(const_cast<String::StringData*>
|
||||||
Assign(Text);
|
Assign(Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String::String(const char* Text, u32 Count) : m_pStringData(const_cast<String::StringData*>(&s_EmptyStringData))
|
||||||
|
{
|
||||||
|
AppendString(Text, Count);
|
||||||
|
}
|
||||||
|
|
||||||
String::String(String&& moveString)
|
String::String(String&& moveString)
|
||||||
{
|
{
|
||||||
Assign(moveString);
|
Assign(moveString);
|
||||||
|
|
|
@ -46,6 +46,9 @@ public:
|
||||||
// For strings that do not allocate any space on the heap, see StaticString.
|
// For strings that do not allocate any space on the heap, see StaticString.
|
||||||
String(const char* Text);
|
String(const char* Text);
|
||||||
|
|
||||||
|
// Creates a string contained the specified text (with length).
|
||||||
|
String(const char* Text, u32 Count);
|
||||||
|
|
||||||
// Creates a string using the same buffer as another string (copy-on-write).
|
// Creates a string using the same buffer as another string (copy-on-write).
|
||||||
String(const String& copyString);
|
String(const String& copyString);
|
||||||
|
|
||||||
|
@ -315,6 +318,12 @@ public:
|
||||||
Assign(Text);
|
Assign(Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StackString(const char* Text, u32 Count) : String(&m_sStringData)
|
||||||
|
{
|
||||||
|
InitStackStringData();
|
||||||
|
AppendString(Text, Count);
|
||||||
|
}
|
||||||
|
|
||||||
StackString(const String& copyString) : String(&m_sStringData)
|
StackString(const String& copyString) : String(&m_sStringData)
|
||||||
{
|
{
|
||||||
// force a copy by passing it a string pointer, instead of a string object
|
// force a copy by passing it a string pointer, instead of a string object
|
||||||
|
|
|
@ -992,14 +992,51 @@ float HostInterface::GetFloatSettingValue(const char* section, const char* key,
|
||||||
return float_value.value_or(default_value);
|
return float_value.value_or(default_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
TinyString HostInterface::TranslateString(const char* context, const char* str) const
|
TinyString HostInterface::TranslateString(const char* context, const char* str,
|
||||||
|
const char* disambiguation /*= nullptr*/, int n /*= -1*/) const
|
||||||
{
|
{
|
||||||
return str;
|
TinyString result(str);
|
||||||
|
if (n >= 0)
|
||||||
|
{
|
||||||
|
const std::string number = std::to_string(n);
|
||||||
|
result.Replace("%n", number.c_str());
|
||||||
|
result.Replace("%Ln", number.c_str());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string HostInterface::TranslateStdString(const char* context, const char* str) const
|
std::string HostInterface::TranslateStdString(const char* context, const char* str,
|
||||||
|
const char* disambiguation /*= nullptr*/, int n /*= -1*/) const
|
||||||
{
|
{
|
||||||
return str;
|
std::string result(str);
|
||||||
|
if (n >= 0)
|
||||||
|
{
|
||||||
|
const std::string number = std::to_string(n);
|
||||||
|
// Made to mimick Qt's behaviour
|
||||||
|
// https://github.com/qt/qtbase/blob/255459250d450286a8c5c492dab3f6d3652171c9/src/corelib/kernel/qcoreapplication.cpp#L2099
|
||||||
|
size_t percent_pos = 0;
|
||||||
|
size_t len = 0;
|
||||||
|
while ((percent_pos = result.find('%', percent_pos + len)) != std::string::npos)
|
||||||
|
{
|
||||||
|
len = 1;
|
||||||
|
if (percent_pos + len == result.length())
|
||||||
|
break;
|
||||||
|
if (result[percent_pos + len] == 'L')
|
||||||
|
{
|
||||||
|
++len;
|
||||||
|
if (percent_pos + len == result.length())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (result[percent_pos + len] == 'n')
|
||||||
|
{
|
||||||
|
++len;
|
||||||
|
result.replace(percent_pos, len, number);
|
||||||
|
len = number.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HostInterface::GetMainDisplayRefreshRate(float* refresh_rate)
|
bool HostInterface::GetMainDisplayRefreshRate(float* refresh_rate)
|
||||||
|
|
|
@ -118,8 +118,10 @@ public:
|
||||||
virtual std::vector<std::string> GetSettingStringList(const char* section, const char* key) = 0;
|
virtual std::vector<std::string> GetSettingStringList(const char* section, const char* key) = 0;
|
||||||
|
|
||||||
/// Translates a string to the current language.
|
/// Translates a string to the current language.
|
||||||
virtual TinyString TranslateString(const char* context, const char* str) const;
|
virtual TinyString TranslateString(const char* context, const char* str, const char* disambiguation = nullptr,
|
||||||
virtual std::string TranslateStdString(const char* context, const char* str) const;
|
int n = -1) const;
|
||||||
|
virtual std::string TranslateStdString(const char* context, const char* str, const char* disambiguation = nullptr,
|
||||||
|
int n = -1) const;
|
||||||
|
|
||||||
/// Returns the refresh rate for the "main" display. Use when it's not possible to query the graphics API for the
|
/// Returns the refresh rate for the "main" display. Use when it's not possible to query the graphics API for the
|
||||||
/// refresh rate of the monitor the window is running in.
|
/// refresh rate of the monitor the window is running in.
|
||||||
|
|
|
@ -127,8 +127,6 @@ void QtHostInterface::shutdownOnThread()
|
||||||
|
|
||||||
void QtHostInterface::installTranslator()
|
void QtHostInterface::installTranslator()
|
||||||
{
|
{
|
||||||
m_translator = std::make_unique<QTranslator>();
|
|
||||||
|
|
||||||
std::string language = GetStringSettingValue("Main", "Language", "");
|
std::string language = GetStringSettingValue("Main", "Language", "");
|
||||||
if (language.empty())
|
if (language.empty())
|
||||||
language = "en";
|
language = "en";
|
||||||
|
@ -143,7 +141,8 @@ void QtHostInterface::installTranslator()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_translator->load(path))
|
auto translator = std::make_unique<QTranslator>(qApp);
|
||||||
|
if (!translator->load(path))
|
||||||
{
|
{
|
||||||
QMessageBox::warning(
|
QMessageBox::warning(
|
||||||
nullptr, QStringLiteral("Translation Error"),
|
nullptr, QStringLiteral("Translation Error"),
|
||||||
|
@ -152,7 +151,7 @@ void QtHostInterface::installTranslator()
|
||||||
}
|
}
|
||||||
|
|
||||||
Log_InfoPrintf("Loaded translation file for language '%s'", language.c_str());
|
Log_InfoPrintf("Loaded translation file for language '%s'", language.c_str());
|
||||||
qApp->installTranslator(m_translator.get());
|
qApp->installTranslator(translator.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtHostInterface::ReportError(const char* message)
|
void QtHostInterface::ReportError(const char* message)
|
||||||
|
@ -1602,22 +1601,17 @@ void QtHostInterface::setImGuiKeyMap()
|
||||||
io.KeyMap[ImGuiKey_Z] = Qt::Key_Z & IMGUI_KEY_MASK;
|
io.KeyMap[ImGuiKey_Z] = Qt::Key_Z & IMGUI_KEY_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
TinyString QtHostInterface::TranslateString(const char* context, const char* str) const
|
TinyString QtHostInterface::TranslateString(const char* context, const char* str,
|
||||||
|
const char* disambiguation /*= nullptr*/, int n /*= -1*/) const
|
||||||
{
|
{
|
||||||
const QString translated(m_translator->translate(context, str));
|
const QByteArray bytes(qApp->translate(context, str, disambiguation, n).toUtf8());
|
||||||
if (translated.isEmpty())
|
return TinyString(bytes.constData(), bytes.size());
|
||||||
return TinyString(str);
|
|
||||||
|
|
||||||
return TinyString(translated.toUtf8().constData());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string QtHostInterface::TranslateStdString(const char* context, const char* str) const
|
std::string QtHostInterface::TranslateStdString(const char* context, const char* str,
|
||||||
|
const char* disambiguation /*= nullptr*/, int n /*= -1*/) const
|
||||||
{
|
{
|
||||||
const QString translated(m_translator->translate(context, str));
|
return qApp->translate(context, str, disambiguation, n).toStdString();
|
||||||
if (translated.isEmpty())
|
|
||||||
return std::string(str);
|
|
||||||
|
|
||||||
return translated.toStdString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QtHostInterface::Thread::Thread(QtHostInterface* parent) : QThread(parent), m_parent(parent) {}
|
QtHostInterface::Thread::Thread(QtHostInterface* parent) : QThread(parent), m_parent(parent) {}
|
||||||
|
|
|
@ -64,8 +64,10 @@ public:
|
||||||
void SetStringListSettingValue(const char* section, const char* key, const std::vector<std::string>& values);
|
void SetStringListSettingValue(const char* section, const char* key, const std::vector<std::string>& values);
|
||||||
void RemoveSettingValue(const char* section, const char* key);
|
void RemoveSettingValue(const char* section, const char* key);
|
||||||
|
|
||||||
TinyString TranslateString(const char* context, const char* str) const override;
|
TinyString TranslateString(const char* context, const char* str, const char* disambiguation = nullptr,
|
||||||
std::string TranslateStdString(const char* context, const char* str) const override;
|
int n = -1) const override;
|
||||||
|
std::string TranslateStdString(const char* context, const char* str, const char* disambiguation = nullptr,
|
||||||
|
int n = -1) const override;
|
||||||
|
|
||||||
bool RequestRenderWindowSize(s32 new_window_width, s32 new_window_height) override;
|
bool RequestRenderWindowSize(s32 new_window_width, s32 new_window_height) override;
|
||||||
void* GetTopLevelWindowHandle() const override;
|
void* GetTopLevelWindowHandle() const override;
|
||||||
|
@ -263,8 +265,6 @@ private:
|
||||||
void queueSettingsSave();
|
void queueSettingsSave();
|
||||||
void wakeThread();
|
void wakeThread();
|
||||||
|
|
||||||
std::unique_ptr<QTranslator> m_translator;
|
|
||||||
|
|
||||||
MainWindow* m_main_window = nullptr;
|
MainWindow* m_main_window = nullptr;
|
||||||
QThread* m_original_thread = nullptr;
|
QThread* m_original_thread = nullptr;
|
||||||
Thread* m_worker_thread = nullptr;
|
Thread* m_worker_thread = nullptr;
|
||||||
|
|
|
@ -41,6 +41,51 @@
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>OSDMessage</name>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>Loaded %n cheats from list.</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>Loaded %n cheat from list.</numerusform>
|
||||||
|
<numerusform>Loaded %n cheats from list.</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source> %n cheats are enabled.</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform> %n cheat is enabled.</numerusform>
|
||||||
|
<numerusform> %n cheats are enabled.</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%n cheats are now active.</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>%n cheat is now active.</numerusform>
|
||||||
|
<numerusform>%n cheats are now active.</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%n cheats are now inactive.</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>%n cheat is now inactive.</numerusform>
|
||||||
|
<numerusform>%n cheats are now inactive.</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>Loaded %n cheats from database.</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>Loaded %n cheat from database.</numerusform>
|
||||||
|
<numerusform>Loaded %n cheats from database.</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>Saved %n cheats to '%s'.</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>Saved %n cheat to '%s'.</numerusform>
|
||||||
|
<numerusform>Saved %n cheats to '%s'.</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>QtHostInterface</name>
|
<name>QtHostInterface</name>
|
||||||
<message numerus="yes">
|
<message numerus="yes">
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1273,10 +1273,10 @@ void CommonHostInterface::DoToggleCheats()
|
||||||
}
|
}
|
||||||
|
|
||||||
cl->SetMasterEnable(!cl->GetMasterEnable());
|
cl->SetMasterEnable(!cl->GetMasterEnable());
|
||||||
AddFormattedOSDMessage(10.0f,
|
AddOSDMessage(cl->GetMasterEnable() ?
|
||||||
cl->GetMasterEnable() ? TranslateString("OSDMessage", "%u cheats are now active.") :
|
TranslateStdString("OSDMessage", "%n cheats are now active.", "", cl->GetEnabledCodeCount()) :
|
||||||
TranslateString("OSDMessage", "%u cheats are now inactive."),
|
TranslateStdString("OSDMessage", "%n cheats are now inactive.", "", cl->GetEnabledCodeCount()),
|
||||||
cl->GetEnabledCodeCount());
|
10.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<CommonHostInterface::HostKeyCode>
|
std::optional<CommonHostInterface::HostKeyCode>
|
||||||
|
@ -3041,8 +3041,9 @@ bool CommonHostInterface::LoadCheatList(const char* filename)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddFormattedOSDMessage(10.0f, TranslateString("OSDMessage", "Loaded %u cheats from list. %u cheats are enabled."),
|
AddOSDMessage(TranslateStdString("OSDMessage", "Loaded %n cheats from list.", "", cl->GetCodeCount()) +
|
||||||
cl->GetCodeCount(), cl->GetEnabledCodeCount());
|
TranslateStdString("OSDMessage", " %n cheats are enabled.", "", cl->GetEnabledCodeCount()),
|
||||||
|
10.0f);
|
||||||
System::SetCheatList(std::move(cl));
|
System::SetCheatList(std::move(cl));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -3068,7 +3069,7 @@ bool CommonHostInterface::LoadCheatListFromDatabase()
|
||||||
if (!cl->LoadFromPackage(System::GetRunningCode()))
|
if (!cl->LoadFromPackage(System::GetRunningCode()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
AddFormattedOSDMessage(10.0f, TranslateString("OSDMessage", "Loaded %u cheats from database."), cl->GetCodeCount());
|
AddOSDMessage(TranslateStdString("OSDMessage", "Loaded %n cheats from database.", "", cl->GetCodeCount()), 10.0f);
|
||||||
System::SetCheatList(std::move(cl));
|
System::SetCheatList(std::move(cl));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -3098,8 +3099,9 @@ bool CommonHostInterface::SaveCheatList(const char* filename)
|
||||||
if (!System::GetCheatList()->SaveToPCSXRFile(filename))
|
if (!System::GetCheatList()->SaveToPCSXRFile(filename))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
AddFormattedOSDMessage(5.0f, TranslateString("OSDMessage", "Saved %u cheats to '%s'."),
|
// This shouldn't be needed, but lupdate doesn't gather this string otherwise...
|
||||||
System::GetCheatList()->GetCodeCount(), filename);
|
const u32 code_count = System::GetCheatList()->GetCodeCount();
|
||||||
|
AddFormattedOSDMessage(5.0f, TranslateString("OSDMessage", "Saved %n cheats to '%s'.", "", code_count), filename);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue