83 lines
3.3 KiB
Python
83 lines
3.3 KiB
Python
|
|
"""
|
|||
|
|
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()) # заменяет выделение
|