34a40ae759
Десктопная галерея и менеджер изображений ComfyUI (PyQt6 + SQLite): - мультипапочный мониторинг (watchdog), грид миниатюр, drag-and-drop - теги, избранное, рейтинг, поиск по промтам - парсер метаданных ComfyUI (PNG/WebP/JPEG), редактор workflow/prompt JSON - перевод выделенного текста через контекстное меню (настраиваемые языки) - отправка промта в очередь ComfyUI с внедрением правок и нового seed - полноэкранный просмотр, локализация ru/en, тёмная тема Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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()) # заменяет выделение
|