One language setting; localized in-memory speech per language

This commit is contained in:
2026-10-09 23:09:07 +02:00
parent 98ec2fe9c4
commit f29af40b37
40 changed files with 77414 additions and 77240 deletions

View File

@@ -30,6 +30,19 @@ TABLE_MIN = 160 # the sound list never gets smaller than thi
ANY = "Any"
def all_languages(ws):
"""Every language the editor offers: speech WADs + subtitle and menu text languages."""
return sorted(set(ws.game.languages) | set(ws.texts.menu_languages()) | set(ws.texts.subtitle_languages()))
def editor_languages(game, language=None):
"""(language, voices): the selected language (default: the game's) and the speech archive used for it
(the language itself, or INT for languages the game has no voices for)."""
lang = (language or game.language() or "INT").upper()
voices = lang if lang in game.languages else ("INT" if "INT" in game.languages else game.languages[0])
return lang, voices
class MainWindow(QMainWindow):
def __init__(self, settings=None, runner=None, game_dir=None):
super().__init__()
@@ -40,6 +53,7 @@ class MainWindow(QMainWindow):
self.player.error.connect(lambda m: self.statusBar().showMessage(m, 5000))
self.userdata = UserData()
self.ws = None
self.language = None # the editor's language (voices, subtitles, menu text)
self.loading = False
self._build()
self._apply_output_device()
@@ -50,7 +64,7 @@ class MainWindow(QMainWindow):
self.resize(1400, 900)
gd = game_dir or default_game_dir(self.settings)
if gd:
QTimer.singleShot(0, lambda: self.load_game(gd, self.settings.get("language")))
QTimer.singleShot(0, lambda: self.load_game(gd)) # always starts in the game's language
else:
self.show_no_game()
@@ -74,11 +88,16 @@ class MainWindow(QMainWindow):
tb.addWidget(title)
tb.addSeparator()
self.cmb_lang = QComboBox()
self.cmb_lang.setToolTip("Speech language archive to browse")
self.cmb_lang.setToolTip("The one language setting of the editor: the voice lines in the Sounds tab, the "
"subtitles and the menu text.\nLanguages without their own voices (e.g. JPN, RUS) "
"use the English (INT) voice lines, like the game.")
self.cmb_lang.activated.connect(lambda _: self.load_game(self.ws.game.root, self.cmb_lang.currentText())
if self.ws else None)
tb.addWidget(QLabel(" Language "))
tb.addWidget(self.cmb_lang)
self.lbl_voices = QLabel()
self.lbl_voices.setObjectName("Muted")
tb.addWidget(self.lbl_voices)
tb.addSeparator()
self.act_revert_all = tb.addAction(icons.icon("revert"), "Revert all", self.revert_all)
self.act_revert_all.setToolTip("Put every original sound back")
@@ -270,7 +289,7 @@ class MainWindow(QMainWindow):
except GameError as e:
self.show_no_game(str(e))
return
lang = language if language in game.languages else game.language()
lang, voices = editor_languages(game, language)
self.loading = True
self.statusBar().showMessage("Loading sound list…")
self.spinner.show()
@@ -279,7 +298,7 @@ class MainWindow(QMainWindow):
def work(job):
avail = available_archives(game)
return W.Workspace(game, store, [a for a in (lang, "SFX", "BANK") if a in avail], full_backup=full,
return W.Workspace(game, store, [a for a in (voices, "SFX", "BANK") if a in avail], full_backup=full,
progress=lambda n, t: job.report("scanning game audio: %d / %d" % (n, t)))
def done(ws):
@@ -287,13 +306,14 @@ class MainWindow(QMainWindow):
self.spinner.hide()
self.ws = ws
self.settings["game_dir"] = game.root
self.settings["language"] = lang
self.save_settings()
self.language = lang
self.cmb_lang.blockSignals(True)
self.cmb_lang.clear()
self.cmb_lang.addItems(game.languages)
self.cmb_lang.addItems(all_languages(ws))
self.cmb_lang.setCurrentText(lang)
self.cmb_lang.blockSignals(False)
self.lbl_voices.setText("" if voices == lang else " voices: %s (no %s voices in the game)" % (voices, lang))
self.populate()
self._text_loaded.clear()
self._tab_changed(self.tabs.currentIndex())
@@ -482,9 +502,6 @@ class MainWindow(QMainWindow):
def show_subtitle(self, key):
"""Subtitles tab with `key` selected (from the sound editor)."""
self.tabs.setCurrentWidget(self.subs)
lang = key.split(":")[1]
if self.subs.lang != lang:
self.subs.load(lang)
self.subs.search.clear()
self.subs.cb_mod.setChecked(False)
for cb in self.subs.filters.values():
@@ -692,7 +709,7 @@ class MainWindow(QMainWindow):
if (self.settings.get("game_dir") != old.get("game_dir") or self.settings.get("store_root") != old.get("store_root")
or self.settings.get("full_backup") != old.get("full_backup")):
if self.settings.get("game_dir"):
self.load_game(self.settings["game_dir"], self.settings.get("language"))
self.load_game(self.settings["game_dir"], self.language)
def _apply_output_device(self):
name = self.settings.get("output_device")