From aff102cccd2f082ac953f02faa3c55937c3620fb Mon Sep 17 00:00:00 2001 From: yupm <35495603+yupm@users.noreply.github.com> Date: Sun, 23 Jul 2023 22:00:29 +0900 Subject: [PATCH] feat: Add option to relocate translate window --- app/components/settings/popups/translate.py | 11 ++++- app/components/views/translate.py | 38 +++++++++++++---- app/components/views/workspace.py | 46 +++++++++++++++++++-- app/components/windows/base.py | 7 ++++ app/services/states.py | 18 +++++++- app/utils/constants.py | 5 +++ 6 files changed, 111 insertions(+), 14 deletions(-) diff --git a/app/components/settings/popups/translate.py b/app/components/settings/popups/translate.py index ebc39b0..98fbb73 100644 --- a/app/components/settings/popups/translate.py +++ b/app/components/settings/popups/translate.py @@ -19,19 +19,22 @@ from PyQt5.QtWidgets import QLabel, QLineEdit, QWidget -from utils.constants import TRANSLATE_MODEL, TOGGLE_CHOICES +from utils.constants import TRANSLATE_MODEL, TOGGLE_CHOICES, TRANSLATE_WINDOW_POSITION from .base import BaseOptions class TranslateOptions(BaseOptions): def __init__(self, parent: QWidget): - super().__init__(parent, [TOGGLE_CHOICES, TRANSLATE_MODEL]) + super().__init__( + parent, [TOGGLE_CHOICES, TRANSLATE_MODEL, TRANSLATE_WINDOW_POSITION] + ) # TODO: Use constants here self.initializeProperties( [ ("enableTranslate", "false", bool), ("translateModel", "ArgosTranslate", str), + ("translateWindowPosition", "Right", str), ] ) @@ -66,11 +69,15 @@ def changeTranslateModel(self, i): except AttributeError as e: print(e) + def changeTranslateWindowPosition(self, i): + self.translateWindowPosition = TRANSLATE_WINDOW_POSITION[i] + def saveSettings(self, hasMessage=True): translateModelName = self.translateModelComboBox.currentText().strip() translateApiKey = self.apiLineEdit.text().strip() self.mainWindow.state.setTranslateModelName(translateModelName) self.mainWindow.state.setTranslateApiKey(translateApiKey) + self.mainWindow.state.setTranslateWindowPosition(self.translateWindowPosition) self.mainWindow.setProperty( "enableTranslate", "true" if self.enableTranslate else "enableTranslate" ) diff --git a/app/components/views/translate.py b/app/components/views/translate.py index c5cab49..eefc9ac 100644 --- a/app/components/views/translate.py +++ b/app/components/views/translate.py @@ -1,5 +1,7 @@ import cutlet -from PyQt5.QtWidgets import QLabel, QTextEdit, QVBoxLayout, QWidget +from PyQt5.QtWidgets import QLabel, QTextEdit, QWidget, QGridLayout +from PyQt5.QtCore import Qt +from utils.constants import TRANSLATE_ITEM_ORIENTATION class TranslateView(QWidget): @@ -9,17 +11,37 @@ def __init__(self, parent=None): self.ocrLineEdit = QTextEdit("") self.romajiLineEdit = QTextEdit("") self.translateLineEdit = QTextEdit("") + self.detectedTextLabel = QLabel("Detected Text") + self.romajiLabel = QLabel("Romaji") + self.translationLabel = QLabel("Translation") - self.setLayout(QVBoxLayout()) - self.layout().addWidget(QLabel("Detected Text")) - self.layout().addWidget(self.ocrLineEdit) - self.layout().addWidget(QLabel("Romaji")) - self.layout().addWidget(self.romajiLineEdit) - self.layout().addWidget(QLabel("Translation")) - self.layout().addWidget(self.translateLineEdit) + self.setLayout(QGridLayout()) + self.setLayoutDirection(Qt.LeftToRight) + self.layout().addWidget(self.detectedTextLabel, 0, 0) + self.layout().addWidget(self.ocrLineEdit, 0, 1) + self.layout().addWidget(self.romajiLabel, 0, 2) + self.layout().addWidget(self.romajiLineEdit, 0, 3) + self.layout().addWidget(self.translationLabel, 0, 4) + self.layout().addWidget(self.translateLineEdit, 0, 5) self.katakanaToRomaji = cutlet.Cutlet() + def changeLayout(self, layout): + widgets = [ + self.layout().itemAt(i).widget() for i in range(self.layout().count()) + ] + for w in widgets: + w.setParent(None) + i = 0 + if layout == TRANSLATE_ITEM_ORIENTATION.HORIZONTAL: + for w in widgets: + self.layout().addWidget(w, i, 0) + i += 1 + elif layout == TRANSLATE_ITEM_ORIENTATION.VERTICAL: + for w in widgets: + self.layout().addWidget(w, 0, i) + i += 1 + def setSourceText(self, text: str): self.ocrLineEdit.setText(text) try: diff --git a/app/components/views/workspace.py b/app/components/views/workspace.py index e886faa..61d02dc 100644 --- a/app/components/views/workspace.py +++ b/app/components/views/workspace.py @@ -26,8 +26,14 @@ from components.popups import BasePopup from components.settings import BaseSettings, ImageScalingOptions, OptionsContainer from services import BaseWorker, State -from utils.constants import EXPLORER_ROOT_DEFAULT, MAIN_VIEW_DEFAULTS, MAIN_VIEW_RATIO +from utils.constants import ( + EXPLORER_ROOT_DEFAULT, + MAIN_VIEW_DEFAULTS, + MAIN_VIEW_RATIO, + TRANSLATE_ITEM_ORIENTATION, +) from utils.scripts import mangaFileToImageDir +from PyQt5 import QtCore class WorkspaceView(QSplitter, BaseSettings): @@ -43,20 +49,54 @@ def __init__(self, parent: QMainWindow, state: State): self.setDefaults(MAIN_VIEW_DEFAULTS) self.loadSettings() + self.splitter = QSplitter() self.translateView = TranslateView(self) self.canvas = OCRView(self, self.state) self.explorer = ImageExplorer(self, self.explorerPath) self.addWidget(self.explorer) - self.addWidget(self.canvas) - self.addWidget(self.translateView) + self.splitter.addWidget(self.translateView) + self.splitter.addWidget(self.canvas) + self.splitter.setLayoutDirection(QtCore.Qt.RightToLeft) + self.splitter.setOrientation(QtCore.Qt.Vertical) + self.splitter.loadPrevImage = self.loadPrevImage + self.splitter.loadNextImage = self.loadNextImage + self.addWidget(self.splitter) + self.setChildrenCollapsible(False) for i, s in enumerate(MAIN_VIEW_RATIO): self.setStretchFactor(i, s) + def translateWindowRight(self): + self.canvas.setParent(None) + self.translateView.setParent(None) + self.translateView.changeLayout(TRANSLATE_ITEM_ORIENTATION.HORIZONTAL) + self.splitter.setOrientation(QtCore.Qt.Horizontal) + self.splitter.addWidget(self.translateView) + self.splitter.addWidget(self.canvas) + + def translateWindowTop(self): + self.canvas.setParent(None) + self.translateView.setParent(None) + self.translateView.changeLayout(TRANSLATE_ITEM_ORIENTATION.VERTICAL) + self.splitter.setOrientation(QtCore.Qt.Vertical) + self.splitter.addWidget(self.translateView) + self.splitter.addWidget(self.canvas) + self.canvas.setMinimumHeight(0.8 * self.height()) + + def translateWindowBottom(self): + self.canvas.setParent(None) + self.translateView.setParent(None) + self.translateView.changeLayout(TRANSLATE_ITEM_ORIENTATION.VERTICAL) + self.splitter.setOrientation(QtCore.Qt.Vertical) + self.splitter.addWidget(self.canvas) + self.splitter.addWidget(self.translateView) + self.canvas.setMinimumHeight(0.8 * self.height()) + def resizeEvent(self, event): self.explorer.setMinimumWidth(0.15 * self.width()) self.canvas.setMinimumWidth(0.6 * self.width()) self.translateView.setMinimumWidth(0.2 * self.width()) + self.canvas.setMinimumHeight(0.8 * self.height()) return super().resizeEvent(event) # ---------------------------------- Explorer ----------------------------------- # diff --git a/app/components/windows/base.py b/app/components/windows/base.py index 51e17b8..7a03123 100644 --- a/app/components/windows/base.py +++ b/app/components/windows/base.py @@ -216,6 +216,13 @@ def loadTranslateAfterPopup(self): self.mainView.translateView.hide() return + if self.state.translateWindowPosition == " Right": + self.mainView.translateWindowRight() + elif self.state.translateWindowPosition == " Top": + self.mainView.translateWindowTop() + elif self.state.translateWindowPosition == " Bottom": + self.mainView.translateWindowBottom() + worker = BaseWorker(self.state.loadTranslateModel) worker.signals.finished.connect(lambda: loadModelButton.setEnabled(True)) diff --git a/app/services/states.py b/app/services/states.py index 9b81138..fe19c4e 100644 --- a/app/services/states.py +++ b/app/services/states.py @@ -75,10 +75,12 @@ def __init__(self): translateModelIndex = settings.value("translateModelIndex", 0) translateModelName = TRANSLATE_MODEL[int(translateModelIndex)].strip() + translateWindowPosition = settings.value("translateWindowPosition", "") translateApiKey = settings.value("translateApiKey", "") self._translateModel = None self._translateModelName: TranslateModelNames = translateModelName self._translateApiKey = translateApiKey + self._translateWindowPosition = translateWindowPosition # ------------------------------------ Image ------------------------------------ # @@ -153,6 +155,18 @@ def translateModel(self): def translateModel(self, translateModel): self._translateModel = translateModel + @property + def translateWindowPosition(self): + return self._translateWindowPosition + + @translateWindowPosition.setter + def translateWindowPosition(self, translateWindowPosition): + self._translateWindowPosition = translateWindowPosition + + def setTranslateWindowPosition(self, translateWindowPosition): + self._translateWindowPosition = translateWindowPosition + return self._translateWindowPosition + @property def translateModelName(self): return self._translateModelName @@ -241,7 +255,9 @@ def predictTranslate(self, text): } try: response = post( - "https://api-free.deepl.com/v2/translate", json=body, headers=headers + "https://api-free.deepl.com/v2/translate", + json=body, + headers=headers, ).json() return response["translations"]["text"].strip() except Exception as e: diff --git a/app/utils/constants.py b/app/utils/constants.py index 9bda736..67ffc70 100644 --- a/app/utils/constants.py +++ b/app/utils/constants.py @@ -18,6 +18,7 @@ from .types import ButtonConfigDict from sys import platform +from enum import Enum # ------------------------------------- General ------------------------------------- # @@ -43,6 +44,10 @@ OCR_MODEL = [" MangaOCR", " Tesseract"] TRANSLATE_MODEL = [" ArgosTranslate", " ChatGPT", " DeepL"] +TRANSLATE_WINDOW_POSITION = [" Right", " Top", " Bottom"] +TRANSLATE_ITEM_ORIENTATION = Enum( + "TRANSLATE_ITEM_ORIENTATION", ["HORIZONTAL", "VERTICAL"] +) LANGUAGE = [" Japanese", " Korean", " Chinese SIM", " Chinese TRA ", " English"] ORIENTATION = [" Vertical", " Horizontal"]