Repository navigation
feat(options): a Translate item names checkbox under the language - #127
Conversation
…translated [UI] TranslateItemNames (default 1) picks the language of the item names: the UI language, or English when it is 0. The item data handler applies it at load, on a language change and when RefreshItemNames() is called after the setting changed. The item help window builds its content again when only the language of the item names changed.
The Interface tab shows it as a part of the language row, in both themes. Unticked, item names switch to English at once while every other text keeps the chosen language; the setting is saved in config.ini. The label is in all eleven game languages.
Mosch0512
left a comment
There was a problem hiding this comment.
Verdict: changes requested for two items; the rest is non-blocking. In the game the setting does what the PR says. It is read and saved with the other [UI] keys, both the locale observer and RefreshItemNames go through ItemNameLocale(), and the item help window builds its content again when only the item name language changes. The two required items are an editor item list that keeps the old names after a toggle, and tests for the part of the change that applies the setting.
Required
- The effect browser's item list keeps the old-language names after the checkbox changes. It builds again only when the UI language or the item data changes (EffectPreviewView.cpp:357, outside the diff; details below).
- No test checks that the setting reaches the item names (load, language switch,
RefreshItemNames) or thatTranslateItemNamesis saved (inline, ItemDataHandler.cpp:220).
Non-blocking
- Each view that caches item names picks its own key for when to build again; one counter on the item database would cover them all (inline, ItemHelpContentKey.cpp:14).
- The item data handler reads
GameConfigitself, so every test that loads item data depends on the config.ini next to the test program (inline, ItemDataHandler.cpp:69). - The editor's CSV export now writes English names while the option is off (ItemDataExportAsCSV.cpp:52, outside the diff; details below).
SyncTranslateItemNamesRowcopies the label sync thatSyncRmlModelalready has (inline, OptionWindow.cpp:993).- A few comments still say item names are in the UI language (ItemDatabase.h:31 and two more, outside the diff; details below).
I read every hunk with its enclosing function, the callers of RefreshItemNames, GetItemHelpContentKey and the new GameConfig getter, every user of SetDisplayLocale and GetDisplayLocale, and every cache in the game and the editor that keeps item names until a version or a language changes. I didn't build or run it. CI: Quality Gates passed; the Windows, Linux and macOS builds were still pending when this was posted.
Outside the diff
src/MuEditor/UI/EffectBrowser/EffectPreviewView.cpp:357
Required. RefreshItems builds the item list from ItemAttribute[itemType].Name and builds it again only when the item database version, the item model version or I18N::GetCurrentLocale() changes. Ticking or unticking Translate item names changes the names in ItemAttribute but none of those three, so the list and its search keep the old names. For example, with the UI in German and an item preview open in the effect browser, untick the option: the list still shows Klinge for (0,5) while the item browser shows Blade, until an item is edited or the language is switched. The docs and the PR description say the editor's item lists follow the setting.
Comparing g_ItemDatabase.GetDisplayLocale() here, as ItemNamesakes::Update and CMuItemCategoriesUI::UpdateRows already do, fixes it. m_itemsLocale would then be a std::string, since GetDisplayLocale() returns one and the current check compares pointers. The comment above the function ("or the language changes") needs the same change.
src/source/Data/DataHandler/ItemData/ItemDataExportAsCSV.cpp:52
Non-blocking. The CSV export writes ItemAttribute[i].Name. Before this PR that was the UI language; now it is English while the option is off, so the language of the exported names depends on a game option the export doesn't mention. If that is intended, a line in the editor docs would say so. If the export should keep the UI language, it can take the names from the item database with an explicit locale, as the S6E3 export does with BuildItemAttributes(locale).
src/source/Data/GameData/ItemData/ItemDatabase.h:31
Non-blocking. Three comments still describe item names as being in the UI language: SetDisplayLocale here ("the names for this UI locale"), ItemToolWindow.cpp:155 ("In the UI language, as the item browser shows it") and EffectPreviewView.cpp:348. Someone who trusts them would key a new cache on I18N::GetCurrentLocale() and repeat the effect browser bug above. "The item name language: the UI language, or English while Translate item names is off" fits all three.
| static_cast<CItemDataHandler*>(context)->RefreshItemNames(); | ||
| } | ||
|
|
||
| void CItemDataHandler::RefreshItemNames() |
There was a problem hiding this comment.
Required. The new tests check GetItemNameLocale, a one-line ternary, and the help window's key. Nothing tests the part that applies the setting: Load with the option off, the locale observer keeping English names after I18N::SetLocale, RefreshItemNames switching the names, and GameConfig reading and writing [UI] TranslateItemNames. If OnLocaleChanged went back to I18N::GetCurrentLocale(), or the WriteBool line went away, every test would still pass, while the game would show translated names again after a language switch or forget the choice on restart.
A test next to "Loading item data fills ItemAttribute in the UI locale" in test_item_database_files.cpp can cover the first three once the handler can be given the setting (see the comment on line 69). test_display_settings_contract.cmake already checks that GameConfig.cpp saves other options (VSync, the look preset); one more require_text there covers this key.
|
|
||
| std::string_view ItemNameLocale() | ||
| { | ||
| return GetItemNameLocale(I18N::GetCurrentLocale(), GameConfig::GetInstance().GetTranslateItemNames()); |
There was a problem hiding this comment.
Non-blocking. ItemNameLocale() makes the item data handler read GameConfig::GetInstance(). Every test that loads item data (ShippedItemAttributes, "Loading item data fills ItemAttribute in the UI locale", and others) now constructs GameConfig, which reads the config.ini next to the test program; the build folder has one in tests/data/Release/. A TranslateItemNames=0 there would make the Portuguese and German name checks fail for a reason unrelated to the code, and a test can't turn the option off without writing that file.
If the handler kept the flag itself (for example SetTranslateItemNames(bool), which refreshes the names), with the startup code setting it from GameConfig and the options window calling it, tests could set it directly, and the required test on line 220 is easy to write.
| return {itemType, | ||
| g_ItemDatabase.GetVersion(), | ||
| I18N::LocaleIndex(I18N::GetCurrentLocale()), | ||
| I18N::LocaleIndex(g_ItemDatabase.GetDisplayLocale().c_str()), |
There was a problem hiding this comment.
Non-blocking. This fixes the one cache of item names that knew about the change, by adding the item name language to its key. The other views that cache item names each choose their own key: the effect browser compares the UI language (the required item above), while ItemNamesakes and the categories window compare GetDisplayLocale(). SetDisplayLocale raises no version, so each view has to know which language to compare. A second counter on ItemDatabase, raised by SetDisplayLocale and Store and kept apart from GetVersion() so the editor's drafts stay, would give all of them one number to compare. That can also be a follow-up.
| CItemDataHandler::GetInstance().RefreshItemNames(); | ||
| } | ||
|
|
||
| void mu::ui::window::COptionWindow::SyncTranslateItemNamesRow(OptionRmlModel& model) |
There was a problem hiding this comment.
Non-blocking. SyncTranslateItemNamesRow repeats the body of SyncRmlModel's syncLabel lambda (convert, compare, MarkDirty) and the one-line bool check every other row uses. Rule 4 of docs/CODING_RULES.md: "Before writing new logic, check if something similar already exists. Don't duplicate." If the function is there for rule 1 (extract from a large function you touch), turning syncLabel into a private member and calling it here keeps one copy and still takes code out of SyncRmlModel.
… flag itself The handler no longer reads GameConfig: start-up sets the flag from [UI] TranslateItemNames and the options window sets it when the checkbox changes. Tests that load item data no longer depend on the config.ini next to the test program, and a test can turn the option off.
…aved Loading with the option off, a language change while it is off and turning it on and off again each leave the item names in the expected language. The display settings contract checks that GameConfig reads and writes [UI] TranslateItemNames and that start-up gives it to the item data handler.
…ames ItemDatabase::GetNameVersion counts the changes of the shown item names: a stored item or another language of the names. The item help window, the namesake labels and the Item Categories rows compare it instead of each choosing a language to compare. A language change does not raise the item version, so the item tools' open edits stay.
…ames The item list of the effect browser's item preview was built again only when the items, their models or the UI language changed, so turning translated item names on or off kept the old names in the list and its search. It compares the item name version now.
…anguage Both exports wrote the names ItemAttribute shows, which are English while translated item names are off. They take the item names of the UI locale from the item database now, as the bmd export takes each language's.
SyncRmlModel's syncLabel lambda becomes the SyncLabel member, and the Translate item names row uses it instead of a copy of its body; its checkbox is synced like every other row's.
The comments that said item names are in the UI language say the item name language now: the UI language, or English while translated item names are off. A cache keyed on the UI language alone would miss the option.
Summary
A Translate item names checkbox in the options window, right under the language (Interface tab, both themes). Unticked, item names stay English while every other text keeps the chosen language — for players who know the items by their English names.
[UI] TranslateItemNamesinconfig.ini.How it works
GameConfigreads and writes[UI] TranslateItemNames(default1);config.ini.templatelists it.CItemDataHandler::SetTranslateItemNamesholds the setting: start-up gives it the saved value, the options window the new one.Data::Items::GetItemNameLocalepicks the language of the item names: the UI language, or English when the setting is off. The handler applies it at load, on a language change and when the setting changes, and refillsItemAttribute.ItemDatabase::GetNameVersioncounts the changes of the shown item names (a stored item, or another language of the names). The item help window, the editor's namesake labels, the Item Categories rows and the effect browser's item list compare it, so they take the names again when the option changes. A language change does not raise the item version, so the item tools' open edits stay.Not covered (on purpose)
Only the item name follows the setting. The rest of the tooltip is still built in code with UI texts and stays in the chosen language: the "Excellent" prefix, option lines, and level-based names such as Box of Kundun +1 or jewel bundles. The planned tooltip data rework replaces that code.
Note
The MU Helper's pickup keywords (sven-n#840) match the shown item name, so with the setting off they match the English names.
Testing
test_item_database(the item name language; the name version),test_item_database_files(loading with the option off, a language change while it is off, turning it on and off; the help window rebuilds when the item names change),theme_file_interface_tests,rml_contract_guard_tests,rml_rcss_syntax,display_settings_contract(GameConfig reads and writes the key, start-up applies it): all pass (Windows, Release, editor on).TranslateItemNames=0is saved; ticked again → German names back. Checked in the legacy and modern theme. Also tried by hand on a local OpenMU.