One language setting; localized in-memory speech per language
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -161,7 +161,7 @@ class SubtitleBox(QWidget):
|
||||
self.lay.removeRow(e)
|
||||
self.edits, self.keys = [], []
|
||||
ws = self.win.ws
|
||||
lines = ws.texts.for_sound(s) if ws and s else []
|
||||
lines = ws.texts.for_sound(s, self.win.language) if ws and s else []
|
||||
if not lines:
|
||||
self.lbl.setText("No subtitle for this sound." if s else "")
|
||||
for b in (self.b_apply, self.b_revert, self.b_open):
|
||||
@@ -251,12 +251,11 @@ class TextPanel(QWidget):
|
||||
self._timer.setInterval(150)
|
||||
self._timer.timeout.connect(self._filter)
|
||||
self.search.textChanged.connect(lambda _: self._timer.start())
|
||||
self.cmb_lang = QComboBox()
|
||||
self.cmb_lang.setToolTip("Language of the texts")
|
||||
self.cmb_lang.activated.connect(lambda _: self.load(self.cmb_lang.currentText()))
|
||||
self.lbl_lang = QLabel()
|
||||
self.lbl_lang.setObjectName("Muted")
|
||||
self.lbl_lang.setToolTip("Change the language with the Language list at the top of the window")
|
||||
top.addWidget(self.search, 1)
|
||||
top.addWidget(QLabel("Language"))
|
||||
top.addWidget(self.cmb_lang)
|
||||
top.addWidget(self.lbl_lang)
|
||||
self.filters = {}
|
||||
names = ("Character", "Category") if self.kind == "subs" else ("File",)
|
||||
for name in names:
|
||||
@@ -349,20 +348,16 @@ class TextPanel(QWidget):
|
||||
return tx.subtitle_languages() if self.kind == "subs" else tx.menu_languages()
|
||||
|
||||
def load(self, lang=None):
|
||||
"""(Re)load the rows of a language (default: the game's language)."""
|
||||
"""(Re)load the rows of a language (default: the window's language)."""
|
||||
ws = self.ws()
|
||||
if not ws:
|
||||
return
|
||||
langs = self.languages()
|
||||
lang = lang if lang in langs else (ws.game.language() if ws.game.language() in langs else
|
||||
(langs[0] if langs else None))
|
||||
self.cmb_lang.blockSignals(True)
|
||||
self.cmb_lang.clear()
|
||||
self.cmb_lang.addItems(langs)
|
||||
if lang:
|
||||
self.cmb_lang.setCurrentText(lang)
|
||||
self.cmb_lang.blockSignals(False)
|
||||
lang = lang or self.win.language
|
||||
if lang not in self.languages():
|
||||
lang = None
|
||||
self.lang = lang
|
||||
self.lbl_lang.setText("Language: %s" % lang if lang else "No %s in this language" % (
|
||||
"subtitles" if self.kind == "subs" else "menu text"))
|
||||
if not lang:
|
||||
self.model.reset([], {})
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user