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