From 21367a6127b108d06a337ef551c715677db1f52d Mon Sep 17 00:00:00 2001 From: Andrew Lanzone Date: Mon, 7 Jul 2025 08:58:21 -0700 Subject: [PATCH] Merge branch 'master' of https://gitlab.com/OpenMW/openmw --- apps/components_tests/lua/testl10n.cpp | 26 +++++++++++++++++++++++++ apps/openmw/mwgui/journalwindow.cpp | 2 +- apps/openmw/mwstate/statemanagerimp.cpp | 5 +++-- components/lua/l10n.cpp | 6 +++++- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/apps/components_tests/lua/testl10n.cpp b/apps/components_tests/lua/testl10n.cpp index b48028a730..5528c0520a 100644 --- a/apps/components_tests/lua/testl10n.cpp +++ b/apps/components_tests/lua/testl10n.cpp @@ -24,6 +24,8 @@ namespace constexpr VFS::Path::NormalizedView test2EnPath("l10n/test2/en.yaml"); constexpr VFS::Path::NormalizedView test3EnPath("l10n/test3/en.yaml"); constexpr VFS::Path::NormalizedView test3DePath("l10n/test3/de.yaml"); + constexpr VFS::Path::NormalizedView test4RuPath("l10n/test4/ru.yaml"); + constexpr VFS::Path::NormalizedView test4EnPath("l10n/test4/en.yaml"); VFSTestFile invalidScript("not a script"); VFSTestFile incorrectScript( @@ -69,6 +71,16 @@ currency: "You have {money, number, currency}" VFSTestFile test2En(R"X( good_morning: "Morning!" you_have_arrows: "Arrows count: {count}" +)X"); + + VFSTestFile test4Ru(R"X( +skill_increase: "Ваш навык {навык} увеличился до {value}" +acrobatics: "Акробатика" +)X"); + + VFSTestFile test4En(R"X( +stat_increase: "Your {stat} has increased to {value}" +speed: "Speed" )X"); struct LuaL10nTest : Test @@ -80,6 +92,8 @@ you_have_arrows: "Arrows count: {count}" { test2EnPath, &test2En }, { test3EnPath, &test1En }, { test3DePath, &test1De }, + { test4RuPath, &test4Ru }, + { test4EnPath, &test4En }, }); LuaUtil::ScriptsConfiguration mCfg; @@ -169,6 +183,18 @@ you_have_arrows: "Arrows count: {count}" l.safe_script("t3 = l10n('Test3', 'de')"); l10nManager.setPreferredLocales({ "en" }); EXPECT_EQ(get(l, "t3('Hello {name}!', {name='World'})"), "Hallo World!"); + + // Test that formatting arguments use a correct encoding + l.safe_script("t4 = l10n('Test4', 'ru')"); + l10nManager.setPreferredLocales({ "ru", "en" }); + EXPECT_EQ(get(l, "t4('skill_increase', {навык='Акробатика', value=100})"), + "Ваш навык Акробатика увеличился до 100"); + EXPECT_EQ(get(l, "t4('skill_increase', {навык=t4('acrobatics'), value=100})"), + "Ваш навык Акробатика увеличился до 100"); + EXPECT_EQ(get(l, "t4('stat_increase', {stat='Speed', value=100})"), + "Your Speed has increased to 100"); + EXPECT_EQ(get(l, "t4('stat_increase', {stat=t4('speed'), value=100})"), + "Your Speed has increased to 100"); }); } } diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index ac44264b76..dcc6c423dd 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -945,7 +945,7 @@ namespace // Scroll the list to keep the active item in view Gui::MWList* list = getWidget(mQuestMode ? QuestsList : TopicsList); int offset = 0; - for (int i = 3; i < static_cast(mSelectedQuest); i++) + for (int i = 4; i < static_cast(mSelectedQuest); i++) offset += mButtons[i]->getHeight(); list->setViewOffset(-offset); } diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index 498d2ab25a..34aa3eaa46 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -332,14 +332,15 @@ void MWState::StateManager::saveGame(std::string_view description, const Slot* s writer.close(); if (stream.fail()) - throw std::runtime_error("Write operation failed (memory stream)"); + throw std::runtime_error( + "Write operation failed (memory stream): " + std::generic_category().message(errno)); // All good, write to file std::ofstream filestream(slot->mPath, std::ios::binary); filestream << stream.rdbuf(); if (filestream.fail()) - throw std::runtime_error("Write operation failed (file stream)"); + throw std::runtime_error("Write operation failed (file stream): " + std::generic_category().message(errno)); Settings::saves().mCharacter.set(Files::pathToUnicodeString(slot->mPath.parent_path().filename())); mLastSavegame = slot->mPath; diff --git a/components/lua/l10n.cpp b/components/lua/l10n.cpp index 15177bea65..ec42992ebb 100644 --- a/components/lua/l10n.cpp +++ b/components/lua/l10n.cpp @@ -18,7 +18,11 @@ namespace { // Argument values if (value.is()) - args.push_back(icu::Formattable(LuaUtil::cast(value).c_str())); + { + const auto& str = LuaUtil::cast(value); + args.push_back(icu::Formattable(icu::UnicodeString::fromUTF8(str.c_str()))); + } + // Note: While we pass all numbers as doubles, they still seem to be handled appropriately. // Numbers can be forced to be integers using the argType number and argStyle integer // E.g. {var, number, integer}