""" QTextEdit / QLineEdit с пунктами «Перевести на …» в контекстном меню. Пункты появляются при наличии выделенного текста; список языков настраивается глобально через set_translate_languages() (из настроек). """ from typing import List from PyQt6.QtWidgets import QTextEdit, QLineEdit from comfy_studio.core.i18n import tr from comfy_studio.services.translator import LANG_NAMES from comfy_studio.ui.widgets.translate_dialog import TranslateDialog # Глобальный список языков перевода (обновляется из настроек) _translate_languages: List[str] = ["ru", "en"] def set_translate_languages(langs: List[str]) -> None: global _translate_languages _translate_languages = [l for l in langs if l in LANG_NAMES] or ["ru", "en"] def get_translate_languages() -> List[str]: return list(_translate_languages) class TranslatableTextEdit(QTextEdit): """QTextEdit с переводом выделенного текста через контекстное меню.""" def contextMenuEvent(self, event): menu = self.createStandardContextMenu() cursor = self.textCursor() selected = cursor.selectedText() if selected.strip() and not self.isReadOnly(): menu.addSeparator() for lang in _translate_languages: lang_name = LANG_NAMES.get(lang, lang) action = menu.addAction(tr("translate_to", lang=lang_name)) action.setData(lang) chosen = menu.exec(event.globalPos()) if chosen and chosen.data() in _translate_languages: self._translate_selection(chosen.data()) def _translate_selection(self, target_lang: str): cursor = self.textCursor() # QTextCursor.selectedText() заменяет переводы строк на U+2029 selected = cursor.selectedText().replace("
", "\n") if not selected.strip(): return dialog = TranslateDialog(selected, target_lang, self) if dialog.exec() == TranslateDialog.DialogCode.Accepted: cursor.insertText(dialog.translated_text()) class TranslatableLineEdit(QLineEdit): """QLineEdit с переводом выделенного текста через контекстное меню.""" def contextMenuEvent(self, event): menu = self.createStandardContextMenu() selected = self.selectedText() if selected.strip() and not self.isReadOnly(): menu.addSeparator() for lang in _translate_languages: lang_name = LANG_NAMES.get(lang, lang) action = menu.addAction(tr("translate_to", lang=lang_name)) action.setData(lang) chosen = menu.exec(event.globalPos()) if chosen and chosen.data() in _translate_languages: self._translate_selection(chosen.data()) def _translate_selection(self, target_lang: str): selected = self.selectedText() if not selected.strip(): return dialog = TranslateDialog(selected, target_lang, self) if dialog.exec() == TranslateDialog.DialogCode.Accepted: self.insert(dialog.translated_text()) # заменяет выделение