diff --git a/core/__init__.py b/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/settings/__init__.py b/core/settings/__init__.py new file mode 100644 index 0000000..1333403 --- /dev/null +++ b/core/settings/__init__.py @@ -0,0 +1,5 @@ +from .base import Settings, settings +from .keys import SettingsKeys +from .values import SettingsValues + +__all__ = ["settings", "Settings", "SettingsKeys", "SettingsValues"] diff --git a/core/settings/base.py b/core/settings/base.py new file mode 100644 index 0000000..7cd944c --- /dev/null +++ b/core/settings/base.py @@ -0,0 +1,44 @@ +import sys +from enum import Enum +from typing import Any + +from PySide6.QtCore import QFileInfo, QSettings, Signal + +from core.singleton import QSingleton + +__all__ = ["Settings"] + +TSettingsKey = str | Enum + + +class Settings(QSettings, metaclass=QSingleton): + updated = Signal(str) + + def __init__(self, parent=None): + super().__init__( + QFileInfo(sys.argv[0]).dir().absoluteFilePath("arcaea_offline.ini"), + QSettings.Format.IniFormat, + parent, + ) + + def __settingsKey(self, key: TSettingsKey) -> str: + if isinstance(key, Enum): + return self.__settingsKey(key.value) + + if isinstance(key, str): + return key + + raise TypeError(f"{key!r} is not a valid key") + + def setValue(self, key: TSettingsKey, value: Any) -> None: + _key = self.__settingsKey(key) + + super().setValue(_key, value) + self.updated.emit(_key) + + def stringValue(self, key: TSettingsKey) -> str | None: + _key = self.__settingsKey(key) + return self.value(_key, None, type=str) + + +settings = Settings() diff --git a/core/settings/keys.py b/core/settings/keys.py new file mode 100644 index 0000000..d0f2f54 --- /dev/null +++ b/core/settings/keys.py @@ -0,0 +1,26 @@ +from dataclasses import dataclass +from enum import StrEnum + + +class _General(StrEnum): + Language = "Language" + DatabaseUrl = "DatabaseUrl" + + +class _Ocr(StrEnum): + KnnModelFile = "Ocr/KnnModelFile" + B30KnnModelFile = "Ocr/B30KnnModelFile" + PhashDatabaseFile = "Ocr/PHashDatabaseFile" + DateSource = "Ocr/DateSource" + + +class _Andreal(StrEnum): + Folder = "Andreal/AndrealFolder" + Executable = "Andreal/AndrealExecutable" + + +@dataclass(frozen=True) +class SettingsKeys: + General = _General + Ocr = _Ocr + Andreal = _Andreal diff --git a/core/settings/values.py b/core/settings/values.py new file mode 100644 index 0000000..1505a30 --- /dev/null +++ b/core/settings/values.py @@ -0,0 +1,17 @@ +from dataclasses import dataclass + + +@dataclass(frozen=True) +class _Ocr_ScoreDateSource: + FileCreated: str = "FileCreated" + FileLastModified: str = "FileLastModified" + + +@dataclass(frozen=True) +class _Ocr: + DateSource = _Ocr_ScoreDateSource() + + +@dataclass(frozen=True) +class SettingsValues: + Ocr = _Ocr() diff --git a/ui/extends/shared/singleton.py b/core/singleton.py similarity index 86% rename from ui/extends/shared/singleton.py rename to core/singleton.py index 2ef9da9..a4dcbba 100644 --- a/ui/extends/shared/singleton.py +++ b/core/singleton.py @@ -14,5 +14,5 @@ class Singleton(type, Generic[T]): return cls._instance -class QObjectSingleton(type(QObject), Singleton): +class QSingleton(type(QObject), Singleton): pass diff --git a/index.py b/index.py index 640c258..046cc81 100644 --- a/index.py +++ b/index.py @@ -9,9 +9,9 @@ from PySide6.QtCore import QCoreApplication, QLocale from PySide6.QtGui import QFontDatabase, QIcon from PySide6.QtWidgets import QApplication, QDialog, QMessageBox -import ui.resources.resources_rc +import ui.resources.resources_rc # noqa: F401 +from core.settings import SettingsKeys, settings 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, DatabaseCheckerResult @@ -59,16 +59,19 @@ if __name__ == "__main__": rootLogger.addHandler(rootLoggerStdOutHandler) app = QApplication(sys.argv) - locale = ( - QLocale(Settings().language()) if Settings().language() else QLocale.system() - ) + settingsLanguage = settings.stringValue(SettingsKeys.General.Language) + locale = QLocale(settingsLanguage) if settingsLanguage else QLocale.system() changeAppLanguage(locale) QFontDatabase.addApplicationFont(":/fonts/GeosansLight.ttf") databaseChecker = DatabaseChecker() databaseChecker.setWindowIcon(QIcon(":/images/icon.png")) - databaseCheckResult = databaseChecker.confirmDb() if Settings().databaseUrl() else 0 + databaseCheckResult = ( + databaseChecker.confirmDb() + if settings.stringValue(SettingsKeys.General.DatabaseUrl) + else 0 + ) if not databaseCheckResult & DatabaseCheckerResult.Initted: result = databaseChecker.exec() diff --git a/ui/extends/shared/data.py b/ui/extends/shared/data.py index b05452d..7e21c96 100644 --- a/ui/extends/shared/data.py +++ b/ui/extends/shared/data.py @@ -7,7 +7,7 @@ from typing import Literal, Optional, overload from arcaea_offline.models import Chart, Difficulty, Song from PySide6.QtCore import QFile -from .singleton import Singleton +from core.singleton import Singleton TPartnerModifier = dict[str, Literal[0, 1, 2]] @@ -48,14 +48,12 @@ class Data(metaclass=Singleton): return self.dataPath / "Arcaea" @overload - def getJacketPath(self, chart: Chart, /) -> Path | None: - ... + def getJacketPath(self, chart: Chart, /) -> Path | None: ... @overload def getJacketPath( self, song: Song, difficulty: Optional[Difficulty] = None, / - ) -> Path | None: - ... + ) -> Path | None: ... def getJacketPath(self, *args) -> Path | None: if isinstance(args[0], Chart): diff --git a/ui/extends/shared/settings.py b/ui/extends/shared/settings.py deleted file mode 100644 index 8c645de..0000000 --- a/ui/extends/shared/settings.py +++ /dev/null @@ -1,122 +0,0 @@ -import sys - -from PySide6.QtCore import QFileInfo, QSettings, Signal - -from .singleton import QObjectSingleton - -__all__ = [ - "LANGUAGE", - "DATABASE_URL", - "KNN_MODEL_FILE", - "B30_KNN_MODEL_FILE", - "PHASH_DATABASE_FILE", - "SCORE_DATE_SOURCE", - "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" - -KNN_MODEL_FILE = "Ocr/KnnModelFile" -B30_KNN_MODEL_FILE = "Ocr/B30KnnModelFile" -PHASH_DATABASE_FILE = "Ocr/PHashDatabaseFile" -SCORE_DATE_SOURCE = "Ocr/DateSource" - -ANDREAL_FOLDER = "Andreal/AndrealFolder" -ANDREAL_EXECUTABLE = "Andreal/AndrealExecutable" - - -class Settings(QSettings, metaclass=QObjectSingleton): - updated = Signal(str) - - def __init__(self, parent=None): - super().__init__( - QFileInfo(sys.argv[0]).dir().absoluteFilePath("arcaea_offline.ini"), - QSettings.Format.IniFormat, - parent, - ) - - def setValue(self, key: str, value) -> None: - super().setValue(key, value) - self.updated.emit(key) - - def _strItem(self, key: str) -> str | None: - return self.value(key, None, str) - - def _setStrItem(self, key: str, value: str): - self.setValue(key, value) - self.sync() - - def _resetStrItem(self, key: str): - 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) - - def setDatabaseUrl(self, value: str): - self._setStrItem(DATABASE_URL, value) - - def knnModelFile(self): - return self._strItem(KNN_MODEL_FILE) - - def setKnnModelFile(self, value: str): - self._setStrItem(KNN_MODEL_FILE, value) - - def resetKnnModelFile(self): - self._resetStrItem(KNN_MODEL_FILE) - - def b30KnnModelFile(self): - return self._strItem(B30_KNN_MODEL_FILE) - - def setB30KnnModelFile(self, value: str): - self._setStrItem(B30_KNN_MODEL_FILE, value) - - def resetB30KnnModelFile(self): - self._resetStrItem(B30_KNN_MODEL_FILE) - - def phashDatabaseFile(self): - return self._strItem(PHASH_DATABASE_FILE) - - def setPHashDatabaseFile(self, value: str): - self._setStrItem(PHASH_DATABASE_FILE, value) - - def resetPHashDatabaseFile(self): - self._resetStrItem(PHASH_DATABASE_FILE) - - def scoreDateSource(self): - return self._strItem(SCORE_DATE_SOURCE) - - def setScoreDateSource(self, value: str): - self._setStrItem(SCORE_DATE_SOURCE, value) - - def resetScoreDateSource(self): - self._resetStrItem(SCORE_DATE_SOURCE) - - 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/extends/tabs/tabOcr/tabOcr_Device.py b/ui/extends/tabs/tabOcr/tabOcr_Device.py index 1287fab..ce58781 100644 --- a/ui/extends/tabs/tabOcr/tabOcr_Device.py +++ b/ui/extends/tabs/tabOcr/tabOcr_Device.py @@ -19,9 +19,9 @@ from arcaea_offline_ocr.phash_db import ImagePhashDatabase from arcaea_offline_ocr.utils import imread_unicode from PySide6.QtCore import QDateTime, QFileInfo +from core.settings import SettingsKeys, SettingsValues, settings from ui.extends.components.ocrQueue import OcrRunnable from ui.extends.shared.data import Data -from ui.extends.shared.settings import Settings logger = logging.getLogger(__name__) @@ -70,8 +70,8 @@ def getImageDate(imagePath: str) -> QDateTime: datetime = QDateTime.fromString(datetimeStr, "yyyy:MM:dd hh:mm:ss") if not isinstance(datetime, QDateTime): - dateSource = Settings().scoreDateSource() - if dateSource == "lastModified": + dateSource = settings.stringValue(SettingsKeys.Ocr.DateSource) + if dateSource == SettingsValues.Ocr.DateSource.FileLastModified: datetime = QFileInfo(imagePath).lastModified() else: datetime = QFileInfo(imagePath).birthTime() diff --git a/ui/implements/components/fileSelector.py b/ui/implements/components/fileSelector.py index 45ee3e6..6e86c04 100644 --- a/ui/implements/components/fileSelector.py +++ b/ui/implements/components/fileSelector.py @@ -2,9 +2,9 @@ from PySide6.QtCore import QDir, QFileInfo, Qt, Signal, Slot from PySide6.QtGui import QDragEnterEvent, QDragLeaveEvent, QDropEvent from PySide6.QtWidgets import QFileDialog, QWidget +from core.settings import settings from ui.designer.components.fileSelector_ui import Ui_FileSelector from ui.extends.shared.language import LanguageChangeEventFilter -from ui.extends.shared.settings import Settings class FileSelector(Ui_FileSelector, QWidget): @@ -122,13 +122,13 @@ class FileSelector(Ui_FileSelector, QWidget): if self.__selectedFiles: return - if value := Settings().value(self.settingsKey): + if value := settings.value(self.settingsKey): self.selectFile(value) - Settings().updated.connect(self.settingsUpdated) + settings.updated.connect(self.settingsUpdated) def disconnectSettings(self): - Settings().updated.disconnect(self.settingsUpdated) + settings.updated.disconnect(self.settingsUpdated) self.settingsKey = None def settingsUpdated(self, key: str): @@ -139,4 +139,4 @@ class FileSelector(Ui_FileSelector, QWidget): if self.__selectedFiles: return - self.selectFile(Settings().value(self.settingsKey)) + self.selectFile(settings.value(self.settingsKey)) diff --git a/ui/implements/components/ocrQueueOptionsDialog.py b/ui/implements/components/ocrQueueOptionsDialog.py index dcb1b6a..f477838 100644 --- a/ui/implements/components/ocrQueueOptionsDialog.py +++ b/ui/implements/components/ocrQueueOptionsDialog.py @@ -1,8 +1,8 @@ from PySide6.QtCore import Signal from PySide6.QtWidgets import QButtonGroup, QDialog +from core.settings import SettingsKeys, SettingsValues, settings from ui.designer.components.ocrQueueOptionsDialog_ui import Ui_OcrQueueOptionsDialog -from ui.extends.shared.settings import Settings class OcrQueueOptionsDialog(QDialog, Ui_OcrQueueOptionsDialog): @@ -29,13 +29,12 @@ class OcrQueueOptionsDialog(QDialog, Ui_OcrQueueOptionsDialog): self.on_scoreDateSourceButtonGroup_buttonClicked ) - self.settings = Settings() - self.settings.updated.connect(self.syncCheckboxesFromSettings) + settings.updated.connect(self.syncCheckboxesFromSettings) self.syncCheckboxesFromSettings() def syncCheckboxesFromSettings(self): - scoreDateSource = self.settings.scoreDateSource() - if scoreDateSource == "lastModified": + scoreDateSource = settings.stringValue(SettingsKeys.Ocr.DateSource) + if scoreDateSource == SettingsValues.Ocr.DateSource.FileLastModified: self.dateUseModifyDateRadioButton.setChecked(True) else: self.dateUseCreationDateRadioButton.setChecked(True) @@ -43,6 +42,8 @@ class OcrQueueOptionsDialog(QDialog, Ui_OcrQueueOptionsDialog): def on_scoreDateSourceButtonGroup_buttonClicked(self, button): buttonId = self.scoreDateSourceButtonGroup.id(button) if buttonId == 1: - self.settings.setScoreDateSource("lastModified") + value = SettingsValues.Ocr.DateSource.FileLastModified else: - self.settings.setScoreDateSource("birthTime") + value = SettingsValues.Ocr.DateSource.FileCreated + + settings.setValue(SettingsKeys.Ocr.DateSource, value) diff --git a/ui/implements/settings/settingsAndreal.py b/ui/implements/settings/settingsAndreal.py index 5373ed8..dd02861 100644 --- a/ui/implements/settings/settingsAndreal.py +++ b/ui/implements/settings/settingsAndreal.py @@ -1,6 +1,7 @@ from PySide6.QtCore import QCoreApplication from PySide6.QtWidgets import QLabel, QPushButton +from core.settings import SettingsKeys, settings from ui.implements.components.fileSelector import FileSelector from ui.implements.settings.settingsBaseWidget import SettingsBaseWidget @@ -14,8 +15,8 @@ class SettingsAndreal(SettingsBaseWidget): self.andrealFolderValueWidget.setMode( self.andrealFolderValueWidget.getExistingDirectory ) - if self.settings.andrealFolder(): - self.andrealFolderValueWidget.selectFile(self.settings.andrealFolder()) + if andrealFolder := settings.stringValue(SettingsKeys.Andreal.Folder): + self.andrealFolderValueWidget.selectFile(andrealFolder) self.andrealFolderValueWidget.filesSelected.connect(self.setAndrealFolder) self.andrealFolderResetButton.clicked.connect(self.resetAndrealFolder) self.insertItem( @@ -25,10 +26,8 @@ class SettingsAndreal(SettingsBaseWidget): self.andrealFolderResetButton, ) - if self.settings.andrealExecutable(): - self.andrealExecutableValueWidget.selectFile( - self.settings.andrealExecutable() - ) + if andrealExecutable := settings.stringValue(SettingsKeys.Andreal.Executable): + self.andrealExecutableValueWidget.selectFile(andrealExecutable) self.andrealExecutableValueWidget.filesSelected.connect( self.setAndrealExecutable ) @@ -44,21 +43,21 @@ class SettingsAndreal(SettingsBaseWidget): selectedFile = self.andrealFolderValueWidget.selectedFiles() if selectedFile and selectedFile[0]: file = selectedFile[0] - self.settings.setAndrealFolder(file) + settings.setValue(SettingsKeys.Andreal.Folder, file) def resetAndrealFolder(self): self.andrealFolderValueWidget.reset() - self.settings.resetAndrealFolder() + settings.setValue(SettingsKeys.Andreal.Folder, None) def setAndrealExecutable(self): selectedFile = self.andrealExecutableValueWidget.selectedFiles() if selectedFile and selectedFile[0]: file = selectedFile[0] - self.settings.setAndrealExecutable(file) + settings.setValue(SettingsKeys.Andreal.Executable, file) def resetAndrealExecutable(self): self.andrealExecutableValueWidget.reset() - self.settings.resetAndrealExecutable() + settings.setValue(SettingsKeys.Andreal.Executable, None) def setupUi(self, *args): self.andrealFolderLabel = QLabel(self) diff --git a/ui/implements/settings/settingsBaseWidget.py b/ui/implements/settings/settingsBaseWidget.py index 8b6bc2a..d096557 100644 --- a/ui/implements/settings/settingsBaseWidget.py +++ b/ui/implements/settings/settingsBaseWidget.py @@ -1,15 +1,15 @@ from PySide6.QtCore import Qt from PySide6.QtWidgets import QLabel, QPushButton, QWidget +from core.settings import settings from ui.designer.settings.settingsBaseWidget_ui import Ui_SettingsBaseWidget from ui.extends.shared.language import LanguageChangeEventFilter -from ui.extends.shared.settings import Settings class SettingsBaseWidget(Ui_SettingsBaseWidget, QWidget): def __init__(self, parent=None): super().__init__(parent) - self.settings = Settings() + self.settings = settings self.languageChangeEventFilter = LanguageChangeEventFilter(self) self.installEventFilter(self.languageChangeEventFilter) diff --git a/ui/implements/settings/settingsGeneral.py b/ui/implements/settings/settingsGeneral.py index c84ac9f..b8afef4 100644 --- a/ui/implements/settings/settingsGeneral.py +++ b/ui/implements/settings/settingsGeneral.py @@ -1,6 +1,4 @@ -import sys - -from PySide6.QtCore import QCoreApplication, QDir, QLocale, QProcess +from PySide6.QtCore import QCoreApplication, QDir, QLocale from PySide6.QtWidgets import ( QApplication, QCheckBox, @@ -10,8 +8,8 @@ from PySide6.QtWidgets import ( QPushButton, ) +from core.settings import SettingsKeys, settings 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 @@ -33,8 +31,8 @@ class SettingsGeneral(SettingsBaseWidget): self.languageFollowSystemCheckBox.toggled.connect( self.changeLanguageFollowSystem ) - if self.settings.language(): - locale = QLocale(self.settings.language()) + if language := settings.stringValue(SettingsKeys.General.Language): + locale = QLocale(language) index = self.languageValueWidget.findData(locale) if index > -1: self.languageValueWidget.setCurrentIndex(index) @@ -51,7 +49,7 @@ class SettingsGeneral(SettingsBaseWidget): self.insertItem( "dbUrl", self.dbUrlLabel, - QLabel(self.settings.databaseUrl()), + QLabel(settings.stringValue(SettingsKeys.General.DatabaseUrl)), self.dbUrlResetButton, ) @@ -59,13 +57,13 @@ class SettingsGeneral(SettingsBaseWidget): locale = self.languageValueWidget.currentData() if locale: changeAppLanguage(locale) - self.settings.setLanguage(localeToCode(locale)) + settings.setValue(SettingsKeys.General.Language, localeToCode(locale)) def changeLanguageFollowSystem(self): followSystem = self.languageFollowSystemCheckBox.isChecked() self.languageValueWidget.setCurrentIndex(-1) if followSystem: - self.settings.remove(LANGUAGE) + settings.remove(SettingsKeys.General.Language) changeAppLanguage(QLocale.system()) self.languageValueWidget.setEnabled(False) else: @@ -80,7 +78,7 @@ class SettingsGeneral(SettingsBaseWidget): QMessageBox.StandardButton.No, ) if userConfirm == QMessageBox.StandardButton.Yes: - self.settings.remove(DATABASE_URL) + settings.remove(SettingsKeys.General.DatabaseUrl) QApplication.instance().quit() def setupUi(self, *args): @@ -99,10 +97,10 @@ class SettingsGeneral(SettingsBaseWidget): # 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 index 803e4a3..66694e5 100644 --- a/ui/implements/settings/settingsOcr.py +++ b/ui/implements/settings/settingsOcr.py @@ -1,6 +1,7 @@ from PySide6.QtCore import QCoreApplication from PySide6.QtWidgets import QLabel, QPushButton +from core.settings import SettingsKeys, settings from ui.implements.components.fileSelector import FileSelector from ui.implements.settings.settingsBaseWidget import SettingsBaseWidget @@ -11,8 +12,8 @@ class SettingsOcr(SettingsBaseWidget): self.setupUi(self) - if self.settings.knnModelFile(): - self.knnModelFileValueWidget.selectFile(self.settings.knnModelFile()) + if knnModelFile := settings.stringValue(SettingsKeys.Ocr.KnnModelFile): + self.knnModelFileValueWidget.selectFile(knnModelFile) self.knnModelFileValueWidget.filesSelected.connect(self.setKnnModelFile) self.knnModelFileResetButton.clicked.connect(self.resetKnnModelFile) self.insertItem( @@ -22,8 +23,8 @@ class SettingsOcr(SettingsBaseWidget): self.knnModelFileResetButton, ) - if self.settings.b30KnnModelFile(): - self.b30KnnModelFileValueWidget.selectFile(self.settings.b30KnnModelFile()) + if b30KnnModelFile := settings.stringValue(SettingsKeys.Ocr.B30KnnModelFile): + self.b30KnnModelFileValueWidget.selectFile(b30KnnModelFile) self.b30KnnModelFileValueWidget.filesSelected.connect(self.setB30KnnModelFile) self.b30KnnModelFileResetButton.clicked.connect(self.resetB30KnnModelFile) self.insertItem( @@ -33,10 +34,10 @@ class SettingsOcr(SettingsBaseWidget): self.b30KnnModelFileResetButton, ) - if self.settings.phashDatabaseFile(): - self.phashDatabaseFileValueWidget.selectFile( - self.settings.phashDatabaseFile() - ) + if phashDatabaseFile := settings.stringValue( + SettingsKeys.Ocr.PhashDatabaseFile + ): + self.phashDatabaseFileValueWidget.selectFile(phashDatabaseFile) self.phashDatabaseFileValueWidget.filesSelected.connect( self.setPHashDatabaseFile ) @@ -52,31 +53,31 @@ class SettingsOcr(SettingsBaseWidget): selectedFile = self.knnModelFileValueWidget.selectedFiles() if selectedFile and selectedFile[0]: file = selectedFile[0] - self.settings.setKnnModelFile(file) + settings.setValue(SettingsKeys.Ocr.KnnModelFile, file) def resetKnnModelFile(self): self.knnModelFileValueWidget.reset() - self.settings.resetKnnModelFile() + settings.setValue(SettingsKeys.Ocr.KnnModelFile, None) def setB30KnnModelFile(self): selectedFile = self.b30KnnModelFileValueWidget.selectedFiles() if selectedFile and selectedFile[0]: file = selectedFile[0] - self.settings.setB30KnnModelFile(file) + settings.setValue(SettingsKeys.Ocr.B30KnnModelFile, file) def resetB30KnnModelFile(self): self.b30KnnModelFileValueWidget.reset() - self.settings.resetB30KnnModelFile() + settings.setValue(SettingsKeys.Ocr.B30KnnModelFile, None) def setPHashDatabaseFile(self): selectedFile = self.phashDatabaseFileValueWidget.selectedFiles() if selectedFile and selectedFile[0]: file = selectedFile[0] - self.settings.setPHashDatabaseFile(file) + settings.setValue(SettingsKeys.Ocr.PhashDatabaseFile, file) def resetPHashDatabaseFile(self): self.phashDatabaseFileValueWidget.reset() - self.settings.resetPHashDatabaseFile() + settings.setValue(SettingsKeys.Ocr.PhashDatabaseFile, None) def setupUi(self, *args): self.knnModelFileLabel = QLabel(self) diff --git a/ui/implements/tabs/tabOcr/tabOcr_B30.py b/ui/implements/tabs/tabOcr/tabOcr_B30.py index 0473c7b..7d5c965 100644 --- a/ui/implements/tabs/tabOcr/tabOcr_B30.py +++ b/ui/implements/tabs/tabOcr/tabOcr_B30.py @@ -9,6 +9,7 @@ from PIL import Image from PySide6.QtCore import Signal, Slot from PySide6.QtWidgets import QFileDialog, QMessageBox, QWidget +from core.settings import SettingsKeys from ui.designer.tabs.tabOcr.tabOcr_B30_ui import Ui_TabOcr_B30 from ui.extends.components.ocrQueue import OcrQueueModel from ui.extends.ocr.dependencies import ( @@ -16,11 +17,6 @@ from ui.extends.ocr.dependencies import ( getPhashDatabaseStatusText, ) from ui.extends.shared.language import LanguageChangeEventFilter -from ui.extends.shared.settings import ( - B30_KNN_MODEL_FILE, - KNN_MODEL_FILE, - PHASH_DATABASE_FILE, -) from ui.extends.tabs.tabOcr.tabOcr_B30 import ChieriV4OcrRunnable, b30ResultToScore logger = logging.getLogger(__name__) @@ -55,9 +51,15 @@ class TabOcr_B30(Ui_TabOcr_B30, QWidget): self.ocr = None logger.info("Applying settings...") - self.dependencies_knnModelSelector.connectSettings(KNN_MODEL_FILE) - self.dependencies_b30KnnModelSelector.connectSettings(B30_KNN_MODEL_FILE) - self.dependencies_phashDatabaseSelector.connectSettings(PHASH_DATABASE_FILE) + self.dependencies_knnModelSelector.connectSettings( + SettingsKeys.Ocr.KnnModelFile + ) + self.dependencies_b30KnnModelSelector.connectSettings( + SettingsKeys.Ocr.B30KnnModelFile + ) + self.dependencies_phashDatabaseSelector.connectSettings( + SettingsKeys.Ocr.PhashDatabaseFile + ) self.ocrQueueModel = OcrQueueModel(self) self.ocrQueue.setModel(self.ocrQueueModel) diff --git a/ui/implements/tabs/tabOcr/tabOcr_Device.py b/ui/implements/tabs/tabOcr/tabOcr_Device.py index 6c5635e..fcbf35a 100644 --- a/ui/implements/tabs/tabOcr/tabOcr_Device.py +++ b/ui/implements/tabs/tabOcr/tabOcr_Device.py @@ -11,10 +11,10 @@ from arcaea_offline_ocr.phash_db import ImagePhashDatabase from PySide6.QtCore import Slot from PySide6.QtWidgets import QApplication, QFileDialog, QMessageBox, QWidget +from core.settings import SettingsKeys from ui.designer.tabs.tabOcr.tabOcr_Device_ui import Ui_TabOcr_Device from ui.extends.components.ocrQueue import OcrQueueModel from ui.extends.shared.language import LanguageChangeEventFilter -from ui.extends.shared.settings import KNN_MODEL_FILE, PHASH_DATABASE_FILE from ui.extends.tabs.tabOcr.tabOcr_Device import ScoreConverter, TabDeviceOcrRunnable logger = logging.getLogger(__name__) @@ -54,8 +54,12 @@ class TabOcr_Device(Ui_TabOcr_Device, QWidget): ) logger.info("Applying settings...") - self.dependencies_knnModelSelector.connectSettings(KNN_MODEL_FILE) - self.dependencies_phashDatabaseSelector.connectSettings(PHASH_DATABASE_FILE) + self.dependencies_knnModelSelector.connectSettings( + SettingsKeys.Ocr.KnnModelFile + ) + self.dependencies_phashDatabaseSelector.connectSettings( + SettingsKeys.Ocr.PhashDatabaseFile + ) self.options_usePresetCheckBox.setChecked(True) self.options_usePresetCheckBox.setEnabled(False) diff --git a/ui/implements/tabs/tabTools/tabTools_Andreal.py b/ui/implements/tabs/tabTools/tabTools_Andreal.py index 8df74e9..e72ad78 100644 --- a/ui/implements/tabs/tabTools/tabTools_Andreal.py +++ b/ui/implements/tabs/tabTools/tabTools_Andreal.py @@ -11,9 +11,9 @@ from PySide6.QtCore import QCoreApplication, QDir, QFileInfo, Qt, Slot from PySide6.QtGui import QGuiApplication, QImage, QPainter, QPaintEvent, QPixmap from PySide6.QtWidgets import QButtonGroup, QFileDialog, QLabel, QMessageBox, QWidget +from core.settings import SettingsKeys from ui.designer.tabs.tabTools.tabTools_Andreal_ui import Ui_TabTools_Andreal from ui.extends.shared.language import LanguageChangeEventFilter -from ui.extends.shared.settings import ANDREAL_EXECUTABLE, ANDREAL_FOLDER from ui.extends.tabs.tabTools.tabTools_Andreal import AndrealHelper from ui.implements.components.chartSelector import ChartSelector from ui.implements.components.songIdSelector import SongIdSelectorMode @@ -80,8 +80,8 @@ class TabTools_Andreal(Ui_TabTools_Andreal, QWidget): self.andrealFolderSelector.filesSelected.connect(self.setHelperPaths) self.andrealExecutableSelector.filesSelected.connect(self.setHelperPaths) - self.andrealFolderSelector.connectSettings(ANDREAL_FOLDER) - self.andrealExecutableSelector.connectSettings(ANDREAL_EXECUTABLE) + self.andrealFolderSelector.connectSettings(SettingsKeys.Andreal.Folder) + self.andrealExecutableSelector.connectSettings(SettingsKeys.Andreal.Executable) self.generatePreviewButton.clicked.connect(self.requestPreview) self.generateImageButton.clicked.connect(self.requestGenerate) @@ -134,10 +134,8 @@ class TabTools_Andreal(Ui_TabTools_Andreal, QWidget): QMessageBox.information( self, None, - # fmt: off QCoreApplication.translate("TabTools_Andreal", "imageWhatIsThisDialog.description"), - # fmt: on - ) + ) # fmt: skip def imageFormat(self): buttonId = self.imageFormatButtonGroup.checkedId() diff --git a/ui/startup/databaseChecker.py b/ui/startup/databaseChecker.py index e62385d..d785063 100644 --- a/ui/startup/databaseChecker.py +++ b/ui/startup/databaseChecker.py @@ -6,8 +6,8 @@ from arcaea_offline.database import Database from PySide6.QtCore import QCoreApplication, QDir, QFileInfo, QSysInfo, Qt, QUrl, Slot from PySide6.QtWidgets import QDialog, QMessageBox +from core.settings import SettingsKeys, settings from ui.extends.shared.database import create_engine -from ui.extends.shared.settings import Settings from .databaseChecker_ui import Ui_DatabaseChecker @@ -29,8 +29,7 @@ class DatabaseChecker(Ui_DatabaseChecker, QDialog): self.dbDirSelector.setMode(self.dbDirSelector.getExistingDirectory) self.confirmDbByExistingSettings = False - self.settings = Settings(self) - if dbUrlString := self.settings.databaseUrl(): + if dbUrlString := settings.stringValue(SettingsKeys.General.DatabaseUrl): dbFileUrl = QUrl(dbUrlString.replace("sqlite://", "file://")) dbFileInfo = QFileInfo(dbFileUrl.toLocalFile()) if dbFileInfo.exists(): @@ -45,6 +44,9 @@ class DatabaseChecker(Ui_DatabaseChecker, QDialog): self.dbDirSelector.selectFile(QDir.currentPath()) self.dbFilenameLineEdit.setText("arcaea_offline.db") + def writeDatabaseUrlToSettings(self, databaseUrl: str): + settings.setValue(SettingsKeys.General.DatabaseUrl, databaseUrl) + def dbPath(self): return QDir(self.dbDirSelector.selectedFiles()[0]) @@ -79,7 +81,7 @@ class DatabaseChecker(Ui_DatabaseChecker, QDialog): db = Database(create_engine(dbSqliteUrl)) if db.check_init(): flags |= DatabaseCheckerResult.Initted - self.settings.setDatabaseUrl(self.dbSqliteUrl().toString()) + self.writeDatabaseUrlToSettings(self.dbSqliteUrl().toString()) return flags @@ -108,20 +110,18 @@ class DatabaseChecker(Ui_DatabaseChecker, QDialog): @Slot() def on_confirmDbPathButton_clicked(self): dbSqliteUrl = self.dbSqliteUrl() - self.settings.setDatabaseUrl(dbSqliteUrl.toString()) + self.writeDatabaseUrlToSettings(dbSqliteUrl.toString()) result = self.confirmDb() if result & DatabaseCheckerResult.Initted: if not self.confirmDbByExistingSettings: - self.settings.setDatabaseUrl(dbSqliteUrl.toString()) + self.writeDatabaseUrlToSettings(dbSqliteUrl.toString()) elif result & DatabaseCheckerResult.FileExist: confirm_try_init = QMessageBox.question( self, None, - # fmt: off QCoreApplication.translate("DatabaseChecker", "dialog.tryInitExistingDatabase"), - # fmt: on - ) + ) # fmt: skip if confirm_try_init == QMessageBox.StandardButton.Yes: try: Database().init(checkfirst=True) @@ -134,10 +134,8 @@ class DatabaseChecker(Ui_DatabaseChecker, QDialog): confirm_new_database = QMessageBox.question( self, None, - # fmt: off QCoreApplication.translate("DatabaseChecker", "dialog.confirmNewDatabase"), - # fmt: on - ) + ) # fmt: skip if confirm_new_database == QMessageBox.StandardButton.Yes: db = Database(create_engine(dbSqliteUrl)) db.init()