From 06ac59091f4d5f87dad51a5f627953436d293612 Mon Sep 17 00:00:00 2001 From: 283375 Date: Fri, 8 Sep 2023 01:01:21 +0800 Subject: [PATCH] refactor: settings & language --- index.py | 23 +-- ui/designer/settings/settingsBaseWidget.ui | 70 +++++++ ui/designer/settings/settingsBaseWidget_ui.py | 62 ++++++ ui/designer/settings/settingsDefault.ui | 171 ---------------- ui/designer/settings/settingsDefault_ui.py | 131 ------------- ui/designer/tabs/tabSettings.ui | 12 +- ui/designer/tabs/tabSettings_ui.py | 8 +- ui/extends/shared/language.py | 66 +++++++ ui/extends/shared/settings.py | 32 ++- ui/implements/components/chartSelector.py | 4 + ui/implements/components/fileSelector.py | 4 + ui/implements/components/ocrQueue.py | 5 + ui/implements/components/scoreEditor.py | 4 + ui/implements/components/songIdSelector.py | 4 + ui/implements/mainwindow.py | 31 +-- ui/implements/settings/settingsAndreal.py | 83 ++++++++ ui/implements/settings/settingsBaseWidget.py | 41 ++++ ui/implements/settings/settingsDefault.py | 98 ---------- ui/implements/settings/settingsGeneral.py | 106 ++++++++++ ui/implements/settings/settingsOcr.py | 147 ++++++++++++++ ui/implements/tabs/tabSettings.py | 57 +++++- ui/resources/translations/en_US.ts | 184 ++++++++++++++---- ui/resources/translations/zh_CN.ts | 180 ++++++++++++++--- 23 files changed, 990 insertions(+), 533 deletions(-) create mode 100644 ui/designer/settings/settingsBaseWidget.ui create mode 100644 ui/designer/settings/settingsBaseWidget_ui.py delete mode 100644 ui/designer/settings/settingsDefault.ui delete mode 100644 ui/designer/settings/settingsDefault_ui.py create mode 100644 ui/extends/shared/language.py create mode 100644 ui/implements/settings/settingsAndreal.py create mode 100644 ui/implements/settings/settingsBaseWidget.py delete mode 100644 ui/implements/settings/settingsDefault.py create mode 100644 ui/implements/settings/settingsGeneral.py create mode 100644 ui/implements/settings/settingsOcr.py diff --git a/index.py b/index.py index c8d04a2..a41cbef 100644 --- a/index.py +++ b/index.py @@ -3,12 +3,14 @@ import sys import traceback from arcaea_offline.database import Database -from PySide6.QtCore import QCoreApplication, QLibraryInfo, QLocale, QTranslator +from PySide6.QtCore import QCoreApplication, QLocale from PySide6.QtGui import QIcon from PySide6.QtWidgets import QApplication, QDialog, QMessageBox import ui.resources.images.images_rc import ui.resources.translations.translations_rc +from ui.extends.shared.language import changeAppLanguage +from ui.extends.shared.settings import Settings from ui.implements.mainwindow import MainWindow from ui.startup.databaseChecker import DatabaseChecker @@ -24,22 +26,11 @@ logging.basicConfig( if __name__ == "__main__": QCoreApplication.setApplicationName("Arcaea Offline") - locale = QLocale.system() - translator = QTranslator() - translator_load_success = translator.load(QLocale.system(), "", "", ":/lang/") - if not translator_load_success: - translator.load(":/lang/en_US.qm") - baseTranslator = QTranslator() - baseTranslator.load( - QLocale.system(), - "qt", - "_", - QLibraryInfo.path(QLibraryInfo.LibraryPath.TranslationsPath), - ) app = QApplication(sys.argv) - - app.installTranslator(translator) - app.installTranslator(baseTranslator) + locale = ( + QLocale(Settings().language()) if Settings().language() else QLocale.system() + ) + changeAppLanguage(locale) databaseChecker = DatabaseChecker() result = databaseChecker.exec() diff --git a/ui/designer/settings/settingsBaseWidget.ui b/ui/designer/settings/settingsBaseWidget.ui new file mode 100644 index 0000000..e605767 --- /dev/null +++ b/ui/designer/settings/settingsBaseWidget.ui @@ -0,0 +1,70 @@ + + + SettingsBaseWidget + + + + 0 + 0 + 641 + 521 + + + + SettingsBaseWidget + + + + + + + 16 + true + + + + Title + + + + + + + Qt::Vertical + + + QSizePolicy::Maximum + + + + 20 + 25 + + + + + + + + 15 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/ui/designer/settings/settingsBaseWidget_ui.py b/ui/designer/settings/settingsBaseWidget_ui.py new file mode 100644 index 0000000..9a08421 --- /dev/null +++ b/ui/designer/settings/settingsBaseWidget_ui.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'settingsBaseWidget.ui' +## +## Created by: Qt User Interface Compiler version 6.5.2 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, + QMetaObject, QObject, QPoint, QRect, + QSize, QTime, QUrl, Qt) +from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, + QFont, QFontDatabase, QGradient, QIcon, + QImage, QKeySequence, QLinearGradient, QPainter, + QPalette, QPixmap, QRadialGradient, QTransform) +from PySide6.QtWidgets import (QApplication, QGridLayout, QLabel, QSizePolicy, + QSpacerItem, QVBoxLayout, QWidget) + +class Ui_SettingsBaseWidget(object): + def setupUi(self, SettingsBaseWidget): + if not SettingsBaseWidget.objectName(): + SettingsBaseWidget.setObjectName(u"SettingsBaseWidget") + SettingsBaseWidget.resize(641, 521) + SettingsBaseWidget.setWindowTitle(u"SettingsBaseWidget") + self.verticalLayout = QVBoxLayout(SettingsBaseWidget) + self.verticalLayout.setObjectName(u"verticalLayout") + self.titleLabel = QLabel(SettingsBaseWidget) + self.titleLabel.setObjectName(u"titleLabel") + font = QFont() + font.setPointSize(16) + font.setBold(True) + self.titleLabel.setFont(font) + self.titleLabel.setText(u"Title") + + self.verticalLayout.addWidget(self.titleLabel) + + self.verticalSpacer = QSpacerItem(20, 25, QSizePolicy.Minimum, QSizePolicy.Maximum) + + self.verticalLayout.addItem(self.verticalSpacer) + + self.gridLayout = QGridLayout() + self.gridLayout.setObjectName(u"gridLayout") + self.gridLayout.setContentsMargins(15, -1, -1, -1) + + self.verticalLayout.addLayout(self.gridLayout) + + self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) + + self.verticalLayout.addItem(self.verticalSpacer_2) + + + self.retranslateUi(SettingsBaseWidget) + + QMetaObject.connectSlotsByName(SettingsBaseWidget) + # setupUi + + def retranslateUi(self, SettingsBaseWidget): + pass + # retranslateUi + diff --git a/ui/designer/settings/settingsDefault.ui b/ui/designer/settings/settingsDefault.ui deleted file mode 100644 index d90c563..0000000 --- a/ui/designer/settings/settingsDefault.ui +++ /dev/null @@ -1,171 +0,0 @@ - - - SettingsDefault - - - - 0 - 0 - 682 - 493 - - - - SettingsDefault - - - - - - - 200 - 0 - - - - - - - - - 0 - 0 - - - - deviceUuid - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - tesseractFile - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - false - - - - 200 - 0 - - - - - - - - - 200 - 0 - - - - - - - - - 0 - 0 - - - - devicesJsonFile - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - resetButton - - - - - - - knnModelFile - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - resetButton - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 500000 - - - - - - - - siftDatabaseFile - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - - - FileSelector - QWidget -
ui.implements.components.fileSelector
- 1 -
- - DevicesComboBox - QComboBox -
ui.implements.components.devicesComboBox
-
-
- - -
diff --git a/ui/designer/settings/settingsDefault_ui.py b/ui/designer/settings/settingsDefault_ui.py deleted file mode 100644 index 0966fc9..0000000 --- a/ui/designer/settings/settingsDefault_ui.py +++ /dev/null @@ -1,131 +0,0 @@ -# -*- coding: utf-8 -*- - -################################################################################ -## Form generated from reading UI file 'settingsDefault.ui' -## -## Created by: Qt User Interface Compiler version 6.5.1 -## -## WARNING! All changes made in this file will be lost when recompiling UI file! -################################################################################ - -from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, - QMetaObject, QObject, QPoint, QRect, - QSize, QTime, QUrl, Qt) -from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, - QFont, QFontDatabase, QGradient, QIcon, - QImage, QKeySequence, QLinearGradient, QPainter, - QPalette, QPixmap, QRadialGradient, QTransform) -from PySide6.QtWidgets import (QApplication, QGridLayout, QLabel, QPushButton, - QSizePolicy, QSpacerItem, QWidget) - -from ui.implements.components.devicesComboBox import DevicesComboBox -from ui.implements.components.fileSelector import FileSelector - -class Ui_SettingsDefault(object): - def setupUi(self, SettingsDefault): - if not SettingsDefault.objectName(): - SettingsDefault.setObjectName(u"SettingsDefault") - SettingsDefault.resize(682, 493) - SettingsDefault.setWindowTitle(u"SettingsDefault") - self.gridLayout = QGridLayout(SettingsDefault) - self.gridLayout.setObjectName(u"gridLayout") - self.devicesComboBox = DevicesComboBox(SettingsDefault) - self.devicesComboBox.setObjectName(u"devicesComboBox") - self.devicesComboBox.setMinimumSize(QSize(200, 0)) - - self.gridLayout.addWidget(self.devicesComboBox, 1, 1, 1, 1) - - self.label_3 = QLabel(SettingsDefault) - self.label_3.setObjectName(u"label_3") - sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_3.sizePolicy().hasHeightForWidth()) - self.label_3.setSizePolicy(sizePolicy) - self.label_3.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) - - self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1) - - self.label_4 = QLabel(SettingsDefault) - self.label_4.setObjectName(u"label_4") - sizePolicy.setHeightForWidth(self.label_4.sizePolicy().hasHeightForWidth()) - self.label_4.setSizePolicy(sizePolicy) - self.label_4.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) - - self.gridLayout.addWidget(self.label_4, 2, 0, 1, 1) - - self.tesseractFileSelector = FileSelector(SettingsDefault) - self.tesseractFileSelector.setObjectName(u"tesseractFileSelector") - self.tesseractFileSelector.setEnabled(False) - self.tesseractFileSelector.setMinimumSize(QSize(200, 0)) - - self.gridLayout.addWidget(self.tesseractFileSelector, 2, 1, 1, 1) - - self.devicesJsonFileSelector = FileSelector(SettingsDefault) - self.devicesJsonFileSelector.setObjectName(u"devicesJsonFileSelector") - self.devicesJsonFileSelector.setMinimumSize(QSize(200, 0)) - - self.gridLayout.addWidget(self.devicesJsonFileSelector, 0, 1, 1, 1) - - self.label_2 = QLabel(SettingsDefault) - self.label_2.setObjectName(u"label_2") - sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth()) - self.label_2.setSizePolicy(sizePolicy) - self.label_2.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) - - self.gridLayout.addWidget(self.label_2, 0, 0, 1, 1) - - self.deviceUuidResetButton = QPushButton(SettingsDefault) - self.deviceUuidResetButton.setObjectName(u"deviceUuidResetButton") - - self.gridLayout.addWidget(self.deviceUuidResetButton, 1, 2, 1, 1) - - self.label = QLabel(SettingsDefault) - self.label.setObjectName(u"label") - self.label.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) - - self.gridLayout.addWidget(self.label, 3, 0, 1, 1) - - self.devicesJsonFileResetButton = QPushButton(SettingsDefault) - self.devicesJsonFileResetButton.setObjectName(u"devicesJsonFileResetButton") - - self.gridLayout.addWidget(self.devicesJsonFileResetButton, 0, 2, 1, 1) - - self.verticalSpacer = QSpacerItem(20, 500000, QSizePolicy.Minimum, QSizePolicy.Expanding) - - self.gridLayout.addItem(self.verticalSpacer, 5, 1, 1, 1) - - self.label_5 = QLabel(SettingsDefault) - self.label_5.setObjectName(u"label_5") - self.label_5.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) - - self.gridLayout.addWidget(self.label_5, 4, 0, 1, 1) - - self.knnModelFileSelector = FileSelector(SettingsDefault) - self.knnModelFileSelector.setObjectName(u"knnModelFileSelector") - - self.gridLayout.addWidget(self.knnModelFileSelector, 3, 1, 1, 1) - - self.siftDatabaseFileSelector = FileSelector(SettingsDefault) - self.siftDatabaseFileSelector.setObjectName(u"siftDatabaseFileSelector") - - self.gridLayout.addWidget(self.siftDatabaseFileSelector, 4, 1, 1, 1) - - self.gridLayout.setColumnStretch(1, 1) - - self.retranslateUi(SettingsDefault) - - QMetaObject.connectSlotsByName(SettingsDefault) - # setupUi - - def retranslateUi(self, SettingsDefault): - self.label_3.setText(QCoreApplication.translate("SettingsDefault", u"deviceUuid", None)) - self.label_4.setText(QCoreApplication.translate("SettingsDefault", u"tesseractFile", None)) - self.label_2.setText(QCoreApplication.translate("SettingsDefault", u"devicesJsonFile", None)) - self.deviceUuidResetButton.setText(QCoreApplication.translate("SettingsDefault", u"resetButton", None)) - self.label.setText(QCoreApplication.translate("SettingsDefault", u"knnModelFile", None)) - self.devicesJsonFileResetButton.setText(QCoreApplication.translate("SettingsDefault", u"resetButton", None)) - self.label_5.setText(QCoreApplication.translate("SettingsDefault", u"siftDatabaseFile", None)) - pass - # retranslateUi - diff --git a/ui/designer/tabs/tabSettings.ui b/ui/designer/tabs/tabSettings.ui index 322d5c3..7ad5da6 100644 --- a/ui/designer/tabs/tabSettings.ui +++ b/ui/designer/tabs/tabSettings.ui @@ -40,6 +40,9 @@ QAbstractItemView::NoEditTriggers + + Qt::IgnoreAction + true @@ -56,19 +59,10 @@ 0 - - - - SettingsDefault - QWidget -
ui.implements.settings.settingsDefault
- 1 -
-
diff --git a/ui/designer/tabs/tabSettings_ui.py b/ui/designer/tabs/tabSettings_ui.py index 29e3397..c7eb94e 100644 --- a/ui/designer/tabs/tabSettings_ui.py +++ b/ui/designer/tabs/tabSettings_ui.py @@ -3,7 +3,7 @@ ################################################################################ ## Form generated from reading UI file 'tabSettings.ui' ## -## Created by: Qt User Interface Compiler version 6.5.0 +## Created by: Qt User Interface Compiler version 6.5.2 ## ## WARNING! All changes made in this file will be lost when recompiling UI file! ################################################################################ @@ -19,8 +19,6 @@ from PySide6.QtWidgets import (QAbstractItemView, QAbstractScrollArea, QApplicat QListWidget, QListWidgetItem, QSizePolicy, QStackedWidget, QWidget) -from ui.implements.settings.settingsDefault import SettingsDefault - class Ui_TabSettings(object): def setupUi(self, TabSettings): if not TabSettings.objectName(): @@ -40,6 +38,7 @@ class Ui_TabSettings(object): self.listWidget.setBaseSize(QSize(100, 0)) self.listWidget.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents) self.listWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) + self.listWidget.setDefaultDropAction(Qt.IgnoreAction) self.listWidget.setAlternatingRowColors(True) self.listWidget.setSelectionBehavior(QAbstractItemView.SelectRows) @@ -52,9 +51,6 @@ class Ui_TabSettings(object): sizePolicy1.setVerticalStretch(0) sizePolicy1.setHeightForWidth(self.stackedWidget.sizePolicy().hasHeightForWidth()) self.stackedWidget.setSizePolicy(sizePolicy1) - self.page_default = SettingsDefault() - self.page_default.setObjectName(u"page_default") - self.stackedWidget.addWidget(self.page_default) self.horizontalLayout.addWidget(self.stackedWidget) diff --git a/ui/extends/shared/language.py b/ui/extends/shared/language.py new file mode 100644 index 0000000..584f3c3 --- /dev/null +++ b/ui/extends/shared/language.py @@ -0,0 +1,66 @@ +from PySide6.QtCore import QEvent, QLibraryInfo, QLocale, QObject, QTranslator +from PySide6.QtWidgets import QApplication + +INSTALLED_TRANSLATORS = [] + + +def changeAppLanguage( + locale: QLocale, + fallbackLocale: QLocale = QLocale("en_US"), +): + app = QApplication.instance() + + for translator in INSTALLED_TRANSLATORS: + app.removeTranslator(translator) + + translator = QTranslator() + translatorLoadSuccess = translator.load(locale, "", "", ":/lang/") + if not translatorLoadSuccess: + translator.load(fallbackLocale, "", "", ":/lang/") + qtTranslator = QTranslator() + qtTranslatorLoadSuccess = qtTranslator.load( + locale, + "qt", + "_", + QLibraryInfo.path(QLibraryInfo.LibraryPath.TranslationsPath), + ) + if not qtTranslatorLoadSuccess: + qtTranslator.load( + fallbackLocale, + "qt", + "_", + QLibraryInfo.path(QLibraryInfo.LibraryPath.TranslationsPath), + ) + + app.installTranslator(translator) + INSTALLED_TRANSLATORS.append(translator) + app.installTranslator(qtTranslator) + INSTALLED_TRANSLATORS.append(qtTranslator) + + +def localeToCode(locale: QLocale): + code = QLocale.languageToCode(locale.language()) + country = locale.country() + if country and country != QLocale.Country.AnyCountry: + code += f"_{QLocale.countryToCode(country)}" + return code + + +def localeToFullName(locale: QLocale): + ret = QLocale.languageToString(locale.language()) + country = locale.country() + if country and country != QLocale.Country.AnyCountry: + ret += f" ({QLocale.countryToString(country)})" + return ret + + +class LanguageChangeEventFilter(QObject): + def eventFilter(self, watched: QObject, event: QEvent) -> bool: + if ( + event.type() == QEvent.Type.LanguageChange + and hasattr(watched, "retranslateUi") + and callable(watched.retranslateUi) + ): + watched.retranslateUi(watched) + + return super().eventFilter(watched, event) diff --git a/ui/extends/shared/settings.py b/ui/extends/shared/settings.py index 93fded4..00f0187 100644 --- a/ui/extends/shared/settings.py +++ b/ui/extends/shared/settings.py @@ -1,5 +1,6 @@ import sys -from PySide6.QtCore import QSettings, QFileInfo + +from PySide6.QtCore import QFileInfo, QSettings __all__ = [ "DATABASE_URL", @@ -8,11 +9,14 @@ __all__ = [ "TESSERACT_FILE", "KNN_MODEL_FILE", "SIFT_DATABASE_FILE", + "ANDREAL_FOLDER", + "ANDREAL_EXECUTABLE", "Settings", ] # a key without slashes will appear in the "General" section # see https://doc.qt.io/qt-6/qsettings.html#Format-enum for details +LANGUAGE = "Language" DATABASE_URL = "DatabaseUrl" DEVICES_JSON_FILE = "Ocr/DevicesJsonFile" @@ -21,7 +25,7 @@ TESSERACT_FILE = "Ocr/TesseractFile" KNN_MODEL_FILE = "Ocr/KnnModelFile" SIFT_DATABASE_FILE = "Ocr/SiftDatabaseFile" -ANDREAL_PATH = "Andreal/AndrealFolderPath" +ANDREAL_FOLDER = "Andreal/AndrealFolder" ANDREAL_EXECUTABLE = "Andreal/AndrealExecutable" @@ -44,6 +48,12 @@ class Settings(QSettings): self.setValue(key, None) self.sync() + def language(self): + return self._strItem(LANGUAGE) + + def setLanguage(self, value: str): + self._setStrItem(LANGUAGE, value) + def databaseUrl(self): return self._strItem(DATABASE_URL) @@ -94,3 +104,21 @@ class Settings(QSettings): def resetSiftDatabaseFile(self): self._resetStrItem(SIFT_DATABASE_FILE) + + def andrealFolder(self): + return self._strItem(ANDREAL_FOLDER) + + def setAndrealFolder(self, value: str): + self._setStrItem(ANDREAL_FOLDER, value) + + def resetAndrealFolder(self): + self._resetStrItem(ANDREAL_FOLDER) + + def andrealExecutable(self): + return self._strItem(ANDREAL_EXECUTABLE) + + def setAndrealExecutable(self, value: str): + self._setStrItem(ANDREAL_EXECUTABLE, value) + + def resetAndrealExecutable(self): + self._resetStrItem(ANDREAL_EXECUTABLE) diff --git a/ui/implements/components/chartSelector.py b/ui/implements/components/chartSelector.py index b2319bb..347f50d 100644 --- a/ui/implements/components/chartSelector.py +++ b/ui/implements/components/chartSelector.py @@ -8,6 +8,7 @@ from PySide6.QtGui import QShowEvent from PySide6.QtWidgets import QWidget from ui.designer.components.chartSelector_ui import Ui_ChartSelector +from ui.extends.shared.language import LanguageChangeEventFilter logger = logging.getLogger(__name__) @@ -20,6 +21,9 @@ class ChartSelector(Ui_ChartSelector, QWidget): self.db = Database() self.setupUi(self) + self.languageChangeEventFilter = LanguageChangeEventFilter(self) + self.installEventFilter(self.languageChangeEventFilter) + self.valueChanged.connect(self.updateResultLabel) self.songIdSelector.valueChanged.connect(self.updateRatingClassEnabled) diff --git a/ui/implements/components/fileSelector.py b/ui/implements/components/fileSelector.py index 84bc369..8dd1f6f 100644 --- a/ui/implements/components/fileSelector.py +++ b/ui/implements/components/fileSelector.py @@ -2,6 +2,7 @@ from PySide6.QtCore import QDir, QFileInfo, QMetaObject, Qt, Signal, Slot from PySide6.QtWidgets import QFileDialog, QWidget from ui.designer.components.fileSelector_ui import Ui_FileSelector +from ui.extends.shared.language import LanguageChangeEventFilter class FileSelector(Ui_FileSelector, QWidget): @@ -13,6 +14,9 @@ class FileSelector(Ui_FileSelector, QWidget): self.setupUi(self) self.reset() + self.languageChangeEventFilter = LanguageChangeEventFilter(self) + self.installEventFilter(self.languageChangeEventFilter) + self.elidedLabel.setElideMode(Qt.TextElideMode.ElideMiddle) self.accepted.connect(self.filesSelected) diff --git a/ui/implements/components/ocrQueue.py b/ui/implements/components/ocrQueue.py index 7afcef8..2292889 100644 --- a/ui/implements/components/ocrQueue.py +++ b/ui/implements/components/ocrQueue.py @@ -12,12 +12,17 @@ from ui.extends.components.ocrQueue import ( OcrQueueTableProxyModel, OcrScoreDelegate, ) +from ui.extends.shared.language import LanguageChangeEventFilter class OcrQueue(Ui_OcrQueue, QWidget): def __init__(self, parent=None): super().__init__(parent) self.setupUi(self) + + self.languageChangeEventFilter = LanguageChangeEventFilter(self) + self.installEventFilter(self.languageChangeEventFilter) + self.__model: Optional[OcrQueueModel] = None self.__tableProxyModel: Optional[OcrQueueTableProxyModel] = None diff --git a/ui/implements/components/scoreEditor.py b/ui/implements/components/scoreEditor.py index b307553..bd1b69e 100644 --- a/ui/implements/components/scoreEditor.py +++ b/ui/implements/components/scoreEditor.py @@ -15,6 +15,7 @@ from PySide6.QtWidgets import ( ) from ui.designer.components.scoreEditor_ui import Ui_ScoreEditor +from ui.extends.shared.language import LanguageChangeEventFilter class ScoreValidateResult(IntEnum): @@ -33,6 +34,9 @@ class ScoreEditor(Ui_ScoreEditor, QWidget): super().__init__(parent) self.setupUi(self) + self.languageChangeEventFilter = LanguageChangeEventFilter(self) + self.installEventFilter(self.languageChangeEventFilter) + self.__validateBeforeAccept = True self.__chart = None self.__score_id = None diff --git a/ui/implements/components/songIdSelector.py b/ui/implements/components/songIdSelector.py index 2003d7f..a5a4d9e 100644 --- a/ui/implements/components/songIdSelector.py +++ b/ui/implements/components/songIdSelector.py @@ -11,6 +11,7 @@ from PySide6.QtWidgets import QCompleter, QWidget from ui.designer.components.songIdSelector_ui import Ui_SongIdSelector from ui.extends.components.songIdSelector import SearchCompleterModel from ui.extends.shared.delegates.descriptionDelegate import DescriptionDelegate +from ui.extends.shared.language import LanguageChangeEventFilter logger = logging.getLogger(__name__) @@ -23,6 +24,9 @@ class SongIdSelector(Ui_SongIdSelector, QWidget): self.db = Database() self.setupUi(self) + self.languageChangeEventFilter = LanguageChangeEventFilter(self) + self.installEventFilter(self.languageChangeEventFilter) + self.previousPackageButton.clicked.connect( lambda: self.quickSwitchSelection("previous", "package") ) diff --git a/ui/implements/mainwindow.py b/ui/implements/mainwindow.py index 9af1e58..241c8be 100644 --- a/ui/implements/mainwindow.py +++ b/ui/implements/mainwindow.py @@ -1,21 +1,7 @@ -from traceback import format_exception - from PySide6.QtWidgets import QMainWindow from ui.designer.mainwindow_ui import Ui_MainWindow -from ui.implements.tabs.tabOcrEntry import TabOcrEntry - -# try: -# import arcaea_offline_ocr - -# from ui.implements.tabs.tabOcr import TabOcr - -# OCR_ENABLED_FLAG = True -# except Exception as e: -# from ui.implements.tabs.tabOcrDisabled import TabOcrDisabled - -# OCR_ENABLED_FLAG = False -# OCR_ERROR_TEXT = "\n".join(format_exception(e)) +from ui.extends.shared.language import LanguageChangeEventFilter class MainWindow(Ui_MainWindow, QMainWindow): @@ -23,16 +9,5 @@ class MainWindow(Ui_MainWindow, QMainWindow): super().__init__(parent) self.setupUi(self) - # currentIndex = self.tabWidget.currentIndex() - # ocrTabIndex = self.tabWidget.indexOf(self.tab_ocr) - # self.tabWidget.removeTab(ocrTabIndex) - # self.tab_ocr.deleteLater() - # if OCR_ENABLED_FLAG: - # self.tab_ocr = TabOcr(self.tabWidget) - # else: - # self.tab_ocr = TabOcrDisabled(self.tabWidget) - # self.tab_ocr.contentLabel.setText(OCR_ERROR_TEXT) - # self.tab_ocr = TabOcrEntry(self.tabWidget) - # self.tabWidget.insertTab(ocrTabIndex, self.tab_ocr, "") - # self.tabWidget.setCurrentIndex(currentIndex) - # self.retranslateUi(self) + self.languageChangeEventFilter = LanguageChangeEventFilter(self) + self.installEventFilter(self.languageChangeEventFilter) diff --git a/ui/implements/settings/settingsAndreal.py b/ui/implements/settings/settingsAndreal.py new file mode 100644 index 0000000..2d6244d --- /dev/null +++ b/ui/implements/settings/settingsAndreal.py @@ -0,0 +1,83 @@ +from PySide6.QtCore import QCoreApplication +from PySide6.QtWidgets import QLabel, QPushButton + +from ui.implements.components.fileSelector import FileSelector +from ui.implements.settings.settingsBaseWidget import SettingsBaseWidget + + +class SettingsAndreal(SettingsBaseWidget): + def __init__(self, parent=None): + super().__init__(parent) + + self.setupUi(self) + + if self.settings.andrealFolder(): + self.andrealFolderValueWidget.selectFile(self.settings.andrealFolder()) + self.andrealFolderValueWidget.filesSelected.connect(self.setAndrealFolder) + self.andrealFolderResetButton.clicked.connect(self.resetAndrealFolder) + self.insertItem( + "andrealFolder", + self.andrealFolderLabel, + self.andrealFolderValueWidget, + self.andrealFolderResetButton, + ) + + if self.settings.andrealExecutable(): + self.andrealExecutableValueWidget.selectFile( + self.settings.andrealExecutable() + ) + self.andrealExecutableValueWidget.filesSelected.connect( + self.setAndrealExecutable + ) + self.andrealExecutableResetButton.clicked.connect(self.resetAndrealExecutable) + self.insertItem( + "andrealExecutable", + self.andrealExecutableLabel, + self.andrealExecutableValueWidget, + self.andrealExecutableResetButton, + ) + + def setAndrealFolder(self): + selectedFile = self.andrealFolderValueWidget.selectedFiles() + if selectedFile and selectedFile[0]: + file = selectedFile[0] + self.settings.setAndrealFolder(file) + + def resetAndrealFolder(self): + self.andrealFolderValueWidget.reset() + self.settings.resetAndrealFolder() + + def setAndrealExecutable(self): + selectedFile = self.andrealExecutableValueWidget.selectedFiles() + if selectedFile and selectedFile[0]: + file = selectedFile[0] + self.settings.setAndrealExecutable(file) + + def resetAndrealExecutable(self): + self.andrealExecutableValueWidget.reset() + self.settings.resetAndrealExecutable() + + def setupUi(self, *args): + self.andrealFolderLabel = QLabel(self) + self.andrealFolderValueWidget = FileSelector(self) + self.andrealFolderResetButton = QPushButton(self) + + self.andrealExecutableLabel = QLabel(self) + self.andrealExecutableValueWidget = FileSelector(self) + self.andrealExecutableResetButton = QPushButton(self) + + super().setupUi(self) + self.retranslateUi() + + def retranslateUi(self, *args): + super().retranslateUi(self) + + # fmt: off + self.setTitle(QCoreApplication.translate("Settings", "andreal.title")) + + self.andrealFolderLabel.setText(QCoreApplication.translate("Settings", "andreal.andrealFolder.label")) + self.andrealFolderResetButton.setText(QCoreApplication.translate("Settings", "resetButton")) + + self.andrealExecutableLabel.setText(QCoreApplication.translate("Settings", "andreal.andrealExecutable.label")) + self.andrealExecutableResetButton.setText(QCoreApplication.translate("Settings", "resetButton")) + # fmt: on diff --git a/ui/implements/settings/settingsBaseWidget.py b/ui/implements/settings/settingsBaseWidget.py new file mode 100644 index 0000000..c2ac6ee --- /dev/null +++ b/ui/implements/settings/settingsBaseWidget.py @@ -0,0 +1,41 @@ +from PySide6.QtCore import QCoreApplication, Qt +from PySide6.QtWidgets import QLabel, QPushButton, QWidget + +from ui.designer.settings.settingsBaseWidget_ui import Ui_SettingsBaseWidget +from ui.extends.shared.settings import Settings + + +class SettingsBaseWidget(Ui_SettingsBaseWidget, QWidget): + def __init__(self, parent=None): + super().__init__(parent) + self.settings = Settings() + + def setTitle(self, title: str): + self.titleLabel.setText(title) + + def insertItem( + self, + prefix: str, + label: QLabel, + valueWidget: QWidget, + resetButton: QPushButton | None = None, + ): + row = self.gridLayout.rowCount() + + label.setObjectName(f"{prefix}Label") + label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignCenter) + self.gridLayout.addWidget(label, row, 0) + + valueWidget.setObjectName(f"{prefix}ValueWidget") + self.gridLayout.addWidget(valueWidget, row, 1) + + if resetButton: + resetButton.setObjectName(f"{prefix}ResetButton") + self.gridLayout.addWidget(resetButton, row, 2) + + def setupUi(self, widget): + super().setupUi(widget) + self.gridLayout.setColumnStretch(1, 1) + + def retranslateUi(self, widget): + super().retranslateUi(widget) diff --git a/ui/implements/settings/settingsDefault.py b/ui/implements/settings/settingsDefault.py deleted file mode 100644 index affff0e..0000000 --- a/ui/implements/settings/settingsDefault.py +++ /dev/null @@ -1,98 +0,0 @@ -import logging - -from PySide6.QtCore import Slot -from PySide6.QtWidgets import QWidget - -from ui.designer.settings.settingsDefault_ui import Ui_SettingsDefault -from ui.extends.ocr import load_devices_json -from ui.extends.shared.settings import * - -logger = logging.getLogger(__name__) - - -class SettingsDefault(Ui_SettingsDefault, QWidget): - def __init__(self, parent=None): - super().__init__(parent) - self.setupUi(self) - - self.settings = Settings(self) - - self.devicesJsonFileSelector.filesSelected.connect(self.fillDevicesComboBox) - self.devicesJsonFileResetButton.clicked.connect(self.resetDevicesJsonFile) - self.deviceUuidResetButton.clicked.connect(self.resetDeviceUuid) - - devicesJsonPath = self.settings.devicesJsonFile() - self.devicesJsonFileSelector.selectFile(devicesJsonPath) - tesseractPath = self.settings.tesseractPath() - self.tesseractFileSelector.selectFile(tesseractPath) - self.knnModelFileSelector.selectFile(self.settings.knnModelFile()) - self.siftDatabaseFileSelector.selectFile(self.settings.siftDatabaseFile()) - - self.devicesJsonFileSelector.accepted.connect( - self.on_devicesJsonFileSelector_accepted - ) - self.tesseractFileSelector.accepted.connect( - self.on_tesseractFileSelector_accepted - ) - self.knnModelFileSelector.accepted.connect( - self.on_knnModelFileSelector_accepted - ) - self.siftDatabaseFileSelector.accepted.connect( - self.on_siftDatabaseFileSelector_accepted - ) - - def setDevicesJsonFile(self): - try: - filename = self.devicesJsonFileSelector.selectedFiles()[0] - devices = load_devices_json(filename) - assert isinstance(devices, list) - self.settings.setDevicesJsonFile(filename) - except Exception as e: - logger.exception("set deviceJsonFile error") - # QMessageBox - return - - def resetDevicesJsonFile(self): - self.devicesJsonFileSelector.reset() - self.settings.resetDevicesJsonFile() - - def on_devicesJsonFileSelector_accepted(self): - self.setDevicesJsonFile() - - def fillDevicesComboBox(self): - devicesJsonPath = self.devicesJsonFileSelector.selectedFiles()[0] - self.devicesComboBox.loadDevicesJson(devicesJsonPath) - - storedDeviceUuid = self.settings.deviceUuid() - self.devicesComboBox.selectDevice(storedDeviceUuid) - - @Slot() - def on_devicesComboBox_activated(self): - device = self.devicesComboBox.currentData() - if device: - self.settings.setDeviceUuid(device.uuid) - - def resetDeviceUuid(self): - self.devicesComboBox.setCurrentIndex(-1) - self.settings.resetDeviceUuid() - - def setTesseractFile(self): - file = self.tesseractFileSelector.selectedFiles()[0] - self.settings.setTesseractPath(file) - - def on_tesseractFileSelector_accepted(self): - self.setTesseractFile() - - def setKnnModelFile(self): - file = self.knnModelFileSelector.selectedFiles()[0] - self.settings.setKnnModelFile(file) - - def on_knnModelFileSelector_accepted(self): - self.setKnnModelFile() - - def setSiftDatabaseFile(self): - file = self.siftDatabaseFileSelector.selectedFiles()[0] - self.settings.setSiftDatabaseFile(file) - - def on_siftDatabaseFileSelector_accepted(self): - self.setSiftDatabaseFile() diff --git a/ui/implements/settings/settingsGeneral.py b/ui/implements/settings/settingsGeneral.py new file mode 100644 index 0000000..57ad139 --- /dev/null +++ b/ui/implements/settings/settingsGeneral.py @@ -0,0 +1,106 @@ +import sys + +from PySide6.QtCore import QCoreApplication, QDir, QLocale, QProcess +from PySide6.QtWidgets import ( + QApplication, + QCheckBox, + QComboBox, + QLabel, + QMessageBox, + QPushButton, +) + +from ui.extends.shared.language import changeAppLanguage, localeToCode, localeToFullName +from ui.extends.shared.settings import DATABASE_URL, LANGUAGE +from ui.implements.settings.settingsBaseWidget import SettingsBaseWidget + + +class SettingsGeneral(SettingsBaseWidget): + def __init__(self, parent=None): + super().__init__(parent) + + self.setupUi(self) + + availableLanguageFiles = QDir(":/lang").entryInfoList(QDir.Filter.Files) + for fileInfo in availableLanguageFiles: + languageCode = fileInfo.baseName() + locale = QLocale(languageCode) + self.languageValueWidget.addItem(localeToFullName(locale), locale) + self.languageValueWidget.setCurrentIndex(-1) + self.languageValueWidget.currentIndexChanged.connect(self.changeLanguage) + self.languageFollowSystemCheckBox.toggled.connect( + self.changeLanguageFollowSystem + ) + if self.settings.language(): + locale = QLocale(self.settings.language()) + index = self.languageValueWidget.findData(locale) + if index > -1: + self.languageValueWidget.setCurrentIndex(index) + else: + self.languageFollowSystemCheckBox.setChecked(True) + self.insertItem("language", self.languageLabel, self.languageValueWidget) + self.gridLayout.addWidget( + self.languageFollowSystemCheckBox, + self.gridLayout.rowCount() - 1, + self.gridLayout.columnCount(), + ) + + self.dbUrlResetButton.clicked.connect(self.resetDbUrl) + self.insertItem( + "dbUrl", + self.dbUrlLabel, + QLabel(self.settings.databaseUrl()), + self.dbUrlResetButton, + ) + + def changeLanguage(self): + locale = self.languageValueWidget.currentData() + if locale: + changeAppLanguage(locale) + self.settings.setLanguage(localeToCode(locale)) + + def changeLanguageFollowSystem(self): + followSystem = self.languageFollowSystemCheckBox.isChecked() + self.languageValueWidget.setCurrentIndex(-1) + if followSystem: + self.settings.remove(LANGUAGE) + changeAppLanguage(QLocale.system()) + self.languageValueWidget.setEnabled(False) + else: + self.languageValueWidget.setEnabled(True) + + def resetDbUrl(self): + userConfirm = QMessageBox.warning( + self, + None, + QCoreApplication.translate("Settings", "general.dbUrlResetWarning"), + QMessageBox.StandardButton.Yes, + QMessageBox.StandardButton.No, + ) + if userConfirm == QMessageBox.StandardButton.Yes: + self.settings.remove(DATABASE_URL) + QApplication.instance().quit() + + def setupUi(self, *args): + self.languageLabel = QLabel(self) + self.languageValueWidget = QComboBox(self) + self.languageFollowSystemCheckBox = QCheckBox(self) + + self.dbUrlLabel = QLabel(self) + self.dbUrlResetButton = QPushButton(self) + + super().setupUi(self) + self.retranslateUi() + + def retranslateUi(self, *args): + super().retranslateUi(self) + + # fmt: off + self.setTitle(QCoreApplication.translate("Settings", "general.title")) + + self.languageLabel.setText(QCoreApplication.translate("Settings", "general.language.label")) + self.languageFollowSystemCheckBox.setText(QCoreApplication.translate("Settings", "general.language.followSystem")) + + self.dbUrlLabel.setText(QCoreApplication.translate("Settings", "general.dbUrl.label")) + self.dbUrlResetButton.setText(QCoreApplication.translate("Settings", "resetButton")) + # fmt: on diff --git a/ui/implements/settings/settingsOcr.py b/ui/implements/settings/settingsOcr.py new file mode 100644 index 0000000..c5f831f --- /dev/null +++ b/ui/implements/settings/settingsOcr.py @@ -0,0 +1,147 @@ +from PySide6.QtCore import QCoreApplication +from PySide6.QtWidgets import QLabel, QPushButton + +from ui.implements.components.devicesComboBox import DevicesComboBox +from ui.implements.components.fileSelector import FileSelector +from ui.implements.settings.settingsBaseWidget import SettingsBaseWidget + + +class SettingsOcr(SettingsBaseWidget): + def __init__(self, parent=None): + super().__init__(parent) + + self.setupUi(self) + + if self.settings.devicesJsonFile(): + self.devicesJsonValueWidget.selectFile(self.settings.devicesJsonFile()) + self.devicesJsonValueWidget.filesSelected.connect(self.setDevicesJson) + self.devicesJsonResetButton.clicked.connect(self.resetDevicesJson) + self.insertItem( + "devicesJson", + self.devicesJsonLabel, + self.devicesJsonValueWidget, + self.devicesJsonResetButton, + ) + + if self.settings.deviceUuid(): + self.deviceUuidValueWidget.selectDevice(self.settings.deviceUuid()) + self.deviceUuidValueWidget.activated.connect(self.setDeviceUuid) + self.deviceUuidResetButton.clicked.connect(self.resetDeviceUuid) + self.insertItem( + "deviceUuid", + self.deviceUuidLabel, + self.deviceUuidValueWidget, + self.deviceUuidResetButton, + ) + + if self.settings.knnModelFile(): + self.knnModelFileValueWidget.selectFile(self.settings.knnModelFile()) + self.knnModelFileValueWidget.filesSelected.connect(self.setKnnModelFile) + self.knnModelFileResetButton.clicked.connect(self.resetKnnModelFile) + self.insertItem( + "knnModelFile", + self.knnModelFileLabel, + self.knnModelFileValueWidget, + self.knnModelFileResetButton, + ) + + if self.settings.siftDatabaseFile(): + self.siftDatabaseFileValueWidget.selectFile( + self.settings.siftDatabaseFile() + ) + self.siftDatabaseFileValueWidget.filesSelected.connect(self.setSiftDatabaseFile) + self.siftDatabaseFileResetButton.clicked.connect(self.resetSiftDatabaseFile) + self.insertItem( + "siftDatabaseFile", + self.siftDatabaseFileLabel, + self.siftDatabaseFileValueWidget, + self.siftDatabaseFileResetButton, + ) + + def setDevicesJson(self): + selectedFile = self.devicesJsonValueWidget.selectedFiles() + if selectedFile and selectedFile[0]: + file = selectedFile[0] + self.settings.setDevicesJsonFile(file) + self.fillDeviceUuidComboBox() + + def fillDeviceUuidComboBox(self): + devicesJsonPath = self.devicesJsonValueWidget.selectedFiles()[0] + self.deviceUuidValueWidget.loadDevicesJson(devicesJsonPath) + + storedDeviceUuid = self.settings.deviceUuid() + self.deviceUuidValueWidget.selectDevice(storedDeviceUuid) + + def resetDevicesJson(self): + self.deviceUuidValueWidget.clear() + self.devicesJsonValueWidget.reset() + self.settings.resetDeviceUuid() + self.settings.resetDevicesJsonFile() + + def setDeviceUuid(self): + device = self.deviceUuidValueWidget.currentData() + if device: + self.settings.setDeviceUuid(device.uuid) + + def resetDeviceUuid(self): + self.deviceUuidValueWidget.setCurrentIndex(-1) + self.settings.resetDeviceUuid() + + def setKnnModelFile(self): + selectedFile = self.knnModelFileValueWidget.selectedFiles() + if selectedFile and selectedFile[0]: + file = selectedFile[0] + self.settings.setKnnModelFile(file) + + def resetKnnModelFile(self): + self.knnModelFileValueWidget.reset() + self.settings.resetKnnModelFile() + + def setSiftDatabaseFile(self): + selectedFile = self.siftDatabaseFileValueWidget.selectedFiles() + if selectedFile and selectedFile[0]: + file = selectedFile[0] + self.settings.setSiftDatabaseFile(file) + + def resetSiftDatabaseFile(self): + self.siftDatabaseFileValueWidget.reset() + self.settings.resetSiftDatabaseFile() + + def setupUi(self, *args): + self.devicesJsonLabel = QLabel(self) + self.devicesJsonValueWidget = FileSelector(self) + self.devicesJsonResetButton = QPushButton(self) + + self.deviceUuidLabel = QLabel(self) + self.deviceUuidValueWidget = DevicesComboBox(self) + self.deviceUuidResetButton = QPushButton(self) + + self.knnModelFileLabel = QLabel(self) + self.knnModelFileValueWidget = FileSelector(self) + self.knnModelFileResetButton = QPushButton(self) + + self.siftDatabaseFileLabel = QLabel(self) + self.siftDatabaseFileValueWidget = FileSelector(self) + self.siftDatabaseFileResetButton = QPushButton(self) + + super().setupUi(self) + self.retranslateUi() + + def retranslateUi(self, *args): + super().retranslateUi(self) + + # fmt: off + self.setTitle(QCoreApplication.translate("Settings", "ocr.title")) + + self.devicesJsonLabel.setText(QCoreApplication.translate("Settings", "ocr.devicesJson.label")) + self.devicesJsonResetButton.setText(QCoreApplication.translate("Settings", "resetButton")) + + self.deviceUuidLabel.setText(QCoreApplication.translate("Settings", "ocr.deviceUuid.label")) + self.deviceUuidResetButton.setText(QCoreApplication.translate("Settings", "resetButton")) + + self.knnModelFileLabel.setText(QCoreApplication.translate("Settings", "ocr.knnModelFile.label")) + self.knnModelFileResetButton.setText(QCoreApplication.translate("Settings", "resetButton")) + + self.siftDatabaseFileLabel.setText(QCoreApplication.translate("Settings", "ocr.siftDatabaseFile.label")) + self.siftDatabaseFileResetButton.setText(QCoreApplication.translate("Settings", "resetButton")) + # fmt: on diff --git a/ui/implements/tabs/tabSettings.py b/ui/implements/tabs/tabSettings.py index 32860ee..4253784 100644 --- a/ui/implements/tabs/tabSettings.py +++ b/ui/implements/tabs/tabSettings.py @@ -1,11 +1,21 @@ -from PySide6.QtCore import QModelIndex, Slot +from PySide6.QtCore import QCoreApplication, Slot from PySide6.QtWidgets import QListWidgetItem, QWidget from ui.designer.tabs.tabSettings_ui import Ui_TabSettings +from ui.extends.shared.language import LanguageChangeEventFilter +from ui.implements.settings.settingsAndreal import SettingsAndreal +from ui.implements.settings.settingsGeneral import SettingsGeneral +from ui.implements.settings.settingsOcr import SettingsOcr -class SettingsEntryItem(QListWidgetItem): - pass +class SettingsLabelItem(QListWidgetItem): + def __init__(self, translatorKey: str): + super().__init__() + self.translatorKey = translatorKey + self.retranslateUi() + + def retranslateUi(self): + self.setText(QCoreApplication.translate("Settings", self.translatorKey)) class TabSettings(Ui_TabSettings, QWidget): @@ -13,11 +23,42 @@ class TabSettings(Ui_TabSettings, QWidget): super().__init__(parent) self.setupUi(self) - self.listWidget.addItem("Default") - self.listWidget.activated.connect(self.switchPage) + self.languageChangeEventFilter = LanguageChangeEventFilter(self) + self.installEventFilter(self.languageChangeEventFilter) + + self.listWidget.itemClicked.connect(self.switchPage) + + self.listWidget.addItem(self.settingsGeneralLabel) + self.stackedWidget.addWidget(self.settingsGeneral) + + self.listWidget.addItem(self.settingsOcrLabel) + self.stackedWidget.addWidget(self.settingsOcr) + + self.listWidget.addItem(self.settingsAndrealLabel) + self.stackedWidget.addWidget(self.settingsAndreal) self.listWidget.setCurrentRow(self.stackedWidget.currentIndex()) - @Slot(QModelIndex) - def switchPage(self, index: QModelIndex): - self.stackedWidget.setCurrentIndex(index.row()) + @Slot(QListWidgetItem) + def switchPage(self, item: QListWidgetItem): + item.setSelected(True) + self.stackedWidget.setCurrentIndex(self.listWidget.indexFromItem(item).row()) + + def setupUi(self, *args): + self.settingsGeneralLabel = SettingsLabelItem("general.title") + self.settingsGeneral = SettingsGeneral(self) + self.settingsOcrLabel = SettingsLabelItem("ocr.title") + self.settingsOcr = SettingsOcr(self) + self.settingsAndrealLabel = SettingsLabelItem("andreal.title") + self.settingsAndreal = SettingsAndreal(self) + super().setupUi(self) + + def retranslateUi(self, *args): + super().retranslateUi(self) + + self.settingsGeneralLabel.retranslateUi() + self.settingsGeneral.retranslateUi() + self.settingsOcrLabel.retranslateUi() + self.settingsOcr.retranslateUi() + self.settingsAndrealLabel.retranslateUi() + self.settingsAndreal.retranslateUi() diff --git a/ui/resources/translations/en_US.ts b/ui/resources/translations/en_US.ts index 0ab1b42..7893bda 100644 --- a/ui/resources/translations/en_US.ts +++ b/ui/resources/translations/en_US.ts @@ -214,67 +214,67 @@ OcrQueue - + queue.title Queue - + iccOptionsGroupBox ICC Profile Options - + icc.ignore Ignore - + icc.usePIL Use PIL - + icc.tryFix Try fix - + queue.addImageButton Add Image - + queue.removeSelected Remove Selected - + queue.removeAll Remove All - + queue.startOcrButton Start OCR - + results Results - + results.acceptSelectedButton Accept Selected - + results.acceptAllButton Accept All - + results.ignoreValidate Ignore validation @@ -408,37 +408,82 @@ validation - SettingsDefault + Settings - - devicesJsonFile - Default devices.json + + andreal.title + Andreal - - deviceUuid - Default Device + + andreal.andrealFolder.label + Andreal Folder - - tesseractFile - tesseract Path - - - - + + + + + + + resetButton Reset - - knnModelFile - Default KNearest Model + + andreal.andrealExecutable.label + Andreal Executable - - siftDatabaseFile - Default SIFT Database File + + general.dbUrlResetWarning + Application will now delete this setting and exit. Reboot application manually to specify a new database file. Continue? + + + + general.title + General + + + + general.language.label + Language + + + + general.language.followSystem + Follow system + + + + general.dbUrl.label + Database URL + + + + ocr.title + OCR + + + + ocr.devicesJson.label + Default devices.json + + + + ocr.deviceUuid.label + Default device + + + + ocr.knnModelFile.label + Default KNearest model + + + + ocr.siftDatabaseFile.label + Default SIFT database file @@ -622,6 +667,79 @@ validation tab.infoLookup Chart Info Lookup + + + tab.andreal + + + + + TabTools_Andreal + + + andrealPathSelector + + + + + andrealExecutableSelector + + + + + imageType + + + + + imageVersion + + + + + exportJsonButton + + + + + generateButton + + + + + previewImage + + + + + imageType.recent + + + + + imageType.best + + + + + imageType.best30 + + + + + imageFormat + + + + + chart + + + + + imageQuality + + TabTools_InfoLookup diff --git a/ui/resources/translations/zh_CN.ts b/ui/resources/translations/zh_CN.ts index d910597..88420dd 100644 --- a/ui/resources/translations/zh_CN.ts +++ b/ui/resources/translations/zh_CN.ts @@ -214,67 +214,67 @@ OcrQueue - + queue.title 队列 - + iccOptionsGroupBox ICC 文件选项 - + icc.ignore 忽略 - + icc.usePIL 使用 PIL 读取 - + icc.tryFix 尝试修复 - + queue.addImageButton 添加图像文件 - + queue.removeSelected 移除选中 - + queue.removeAll 移除所有 - + queue.startOcrButton 开始 OCR - + results 结果 - + results.acceptSelectedButton 提交选中 - + results.acceptAllButton 提交所有 - + results.ignoreValidate 忽略验证 @@ -407,36 +407,81 @@ - SettingsDefault + Settings - - devicesJsonFile - 默认设备文件 + + andreal.title + Andreal - - deviceUuid - 默认设备 + + andreal.andrealFolder.label + Andreal 文件夹 - - tesseractFile - tesseract 路径 - - - - + + + + + + + resetButton 重置 - - knnModelFile + + andreal.andrealExecutable.label + Andreal 可执行文件 + + + + general.dbUrlResetWarning + 即将删除该设置项并关闭应用,手动重启后即可再次指定数据库路径。是否继续? + + + + general.title + 通用 + + + + general.language.label + 语言 + + + + general.language.followSystem + 跟随系统 + + + + general.dbUrl.label + 数据库 URL + + + + ocr.title + OCR + + + + ocr.devicesJson.label + 默认设备定义文件 + + + + ocr.deviceUuid.label + 默认设备 + + + + ocr.knnModelFile.label 默认 KNearest 模型 - - siftDatabaseFile + + ocr.siftDatabaseFile.label 默认 SIFT 特征值数据库 @@ -621,6 +666,79 @@ tab.infoLookup 查询谱面信息 + + + tab.andreal + + + + + TabTools_Andreal + + + andrealPathSelector + + + + + andrealExecutableSelector + + + + + imageType + + + + + imageVersion + + + + + exportJsonButton + + + + + generateButton + + + + + previewImage + + + + + imageType.recent + + + + + imageType.best + + + + + imageType.best30 + + + + + imageFormat + + + + + chart + + + + + imageQuality + + TabTools_InfoLookup