diff --git a/dikte/app.py b/dikte/app.py index a098199..33933f1 100644 --- a/dikte/app.py +++ b/dikte/app.py @@ -903,6 +903,7 @@ class Dikte: if self.settings_window is None: self.settings_window = SettingsWindow(self.conf, self.meetings) self.settings_window.applied.connect(self._apply_settings) + self.settings_window.language_changed.connect(self._reopen_settings) self.settings_window.finished.connect(self._settings_closed) self.settings_window.show() self.settings_window.raise_() @@ -912,6 +913,31 @@ class Dikte: # Don't drop the object while its own signal is still being delivered. QTimer.singleShot(0, lambda: setattr(self, "settings_window", None)) + def _reopen_settings(self): + """Replace the settings window, so a language change reaches it too. + + A save switches the language everywhere strings are made at the moment + they are shown: the tray is rebuilt, the indicator and the message box + translate as they speak. The settings window is the one place written + once, at construction, so the window that took the new language is the + one place still showing the old one. A fresh window comes up where the + old one stood, on the same tab. + """ + old = self.settings_window + if old is None: + return + tab = old.tabs.currentIndex() + geometry = old.geometry() + # Replaced rather than merely closed: left connected, _settings_closed + # would drop the reference to the new window a moment after it is made. + old.finished.disconnect(self._settings_closed) + old.close() + old.deleteLater() + self.settings_window = None + self.open_settings() + self.settings_window.tabs.setCurrentIndex(tab) + self.settings_window.setGeometry(geometry) + def _apply_local(self): """Pass the local settings on, and hold the models ready if asked to. diff --git a/dikte/i18n.py b/dikte/i18n.py index 6a29fec..c5dc63a 100644 --- a/dikte/i18n.py +++ b/dikte/i18n.py @@ -158,8 +158,6 @@ TR = { "Automatic (system)": "Otomatik (sistem)", "Turkish": "Türkçe", "English": "İngilizce", - "Restart Dikte for the language change to reach every window.": - "Dil değişikliğinin her pencereye işlemesi için Dikte'yi yeniden başlat.", "Microphone": "Mikrofon", "Default microphone": "Varsayılan mikrofon", "Speech language": "Konuşma dili", diff --git a/dikte/settings_ui.py b/dikte/settings_ui.py index 1a73968..eccda97 100644 --- a/dikte/settings_ui.py +++ b/dikte/settings_ui.py @@ -21,6 +21,7 @@ from . import config as cfg from . import filetranscribe from . import ggml from . import hotkey +from . import i18n from . import ipc from . import meeting from . import paste @@ -512,6 +513,10 @@ class LocalModelBox(QGroupBox): class SettingsWindow(QDialog): applied = pyqtSignal() + # A save changed the interface language. Every label below is translated + # as the window is built, so the change cannot reach this window: the + # owner replaces it with a fresh one instead. + language_changed = pyqtSignal() _models_loaded = pyqtSignal(list, str) _transcribe_models_loaded = pyqtSignal(list, str) @@ -533,6 +538,8 @@ class SettingsWindow(QDialog): self._key_fields = {} self._testers = {} self._shown_provider = "" + # What _save compares against to know a rebuild is due. + self._built_language = i18n.language() self.transcriber = FileTranscriber(conf, self) self.setWindowTitle(t("Dikte Settings")) @@ -627,9 +634,6 @@ class SettingsWindow(QDialog): self.ui_language = QComboBox() for label, code in UI_LANGUAGES: self.ui_language.addItem(t(label), code) - self.ui_language.setToolTip( - t("Restart Dikte for the language change to reach every window.") - ) form.addRow(t("Interface language"), self.ui_language) self.mic = QComboBox() @@ -1744,7 +1748,14 @@ class SettingsWindow(QDialog): print(f"dikte: could not trim the history ({exc})") self._load_history() # the trim may just have dropped rows from the list self.applied.emit() + # conf.save() has switched the language t() speaks, so the message box + # already answers in the new one; the labels around it were translated + # when the window was built and stay behind. Asking for the rebuild + # waits until the box is dismissed, so the window is not pulled out + # from under a dialog it is holding up. QMessageBox.information(self, t("Dikte Settings"), t("Saved successfully.")) + if i18n.language() != self._built_language: + self.language_changed.emit() @staticmethod def _select_data(combo, value):