refactor: moving ui.extends to core

* Settings and Singletons moved
This commit is contained in:
283375 2024-06-20 21:30:21 +08:00
parent da3ac7acb3
commit a9d7681ee7
Signed by: 283375
SSH Key Fingerprint: SHA256:UcX0qg6ZOSDOeieKPGokA5h7soykG61nz2uxuQgVLSk
20 changed files with 188 additions and 216 deletions

0
core/__init__.py Normal file
View File

View File

@ -0,0 +1,5 @@
from .base import Settings, settings
from .keys import SettingsKeys
from .values import SettingsValues
__all__ = ["settings", "Settings", "SettingsKeys", "SettingsValues"]

44
core/settings/base.py Normal file
View File

@ -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()

26
core/settings/keys.py Normal file
View File

@ -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

17
core/settings/values.py Normal file
View File

@ -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()

View File

@ -14,5 +14,5 @@ class Singleton(type, Generic[T]):
return cls._instance return cls._instance
class QObjectSingleton(type(QObject), Singleton): class QSingleton(type(QObject), Singleton):
pass pass

View File

@ -9,9 +9,9 @@ from PySide6.QtCore import QCoreApplication, QLocale
from PySide6.QtGui import QFontDatabase, QIcon from PySide6.QtGui import QFontDatabase, QIcon
from PySide6.QtWidgets import QApplication, QDialog, QMessageBox 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.language import changeAppLanguage
from ui.extends.shared.settings import Settings
from ui.implements.mainwindow import MainWindow from ui.implements.mainwindow import MainWindow
from ui.startup.databaseChecker import DatabaseChecker, DatabaseCheckerResult from ui.startup.databaseChecker import DatabaseChecker, DatabaseCheckerResult
@ -59,16 +59,19 @@ if __name__ == "__main__":
rootLogger.addHandler(rootLoggerStdOutHandler) rootLogger.addHandler(rootLoggerStdOutHandler)
app = QApplication(sys.argv) app = QApplication(sys.argv)
locale = ( settingsLanguage = settings.stringValue(SettingsKeys.General.Language)
QLocale(Settings().language()) if Settings().language() else QLocale.system() locale = QLocale(settingsLanguage) if settingsLanguage else QLocale.system()
)
changeAppLanguage(locale) changeAppLanguage(locale)
QFontDatabase.addApplicationFont(":/fonts/GeosansLight.ttf") QFontDatabase.addApplicationFont(":/fonts/GeosansLight.ttf")
databaseChecker = DatabaseChecker() databaseChecker = DatabaseChecker()
databaseChecker.setWindowIcon(QIcon(":/images/icon.png")) 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: if not databaseCheckResult & DatabaseCheckerResult.Initted:
result = databaseChecker.exec() result = databaseChecker.exec()

View File

@ -7,7 +7,7 @@ from typing import Literal, Optional, overload
from arcaea_offline.models import Chart, Difficulty, Song from arcaea_offline.models import Chart, Difficulty, Song
from PySide6.QtCore import QFile from PySide6.QtCore import QFile
from .singleton import Singleton from core.singleton import Singleton
TPartnerModifier = dict[str, Literal[0, 1, 2]] TPartnerModifier = dict[str, Literal[0, 1, 2]]
@ -48,14 +48,12 @@ class Data(metaclass=Singleton):
return self.dataPath / "Arcaea" return self.dataPath / "Arcaea"
@overload @overload
def getJacketPath(self, chart: Chart, /) -> Path | None: def getJacketPath(self, chart: Chart, /) -> Path | None: ...
...
@overload @overload
def getJacketPath( def getJacketPath(
self, song: Song, difficulty: Optional[Difficulty] = None, / self, song: Song, difficulty: Optional[Difficulty] = None, /
) -> Path | None: ) -> Path | None: ...
...
def getJacketPath(self, *args) -> Path | None: def getJacketPath(self, *args) -> Path | None:
if isinstance(args[0], Chart): if isinstance(args[0], Chart):

View File

@ -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)

View File

@ -19,9 +19,9 @@ from arcaea_offline_ocr.phash_db import ImagePhashDatabase
from arcaea_offline_ocr.utils import imread_unicode from arcaea_offline_ocr.utils import imread_unicode
from PySide6.QtCore import QDateTime, QFileInfo from PySide6.QtCore import QDateTime, QFileInfo
from core.settings import SettingsKeys, SettingsValues, settings
from ui.extends.components.ocrQueue import OcrRunnable from ui.extends.components.ocrQueue import OcrRunnable
from ui.extends.shared.data import Data from ui.extends.shared.data import Data
from ui.extends.shared.settings import Settings
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -70,8 +70,8 @@ def getImageDate(imagePath: str) -> QDateTime:
datetime = QDateTime.fromString(datetimeStr, "yyyy:MM:dd hh:mm:ss") datetime = QDateTime.fromString(datetimeStr, "yyyy:MM:dd hh:mm:ss")
if not isinstance(datetime, QDateTime): if not isinstance(datetime, QDateTime):
dateSource = Settings().scoreDateSource() dateSource = settings.stringValue(SettingsKeys.Ocr.DateSource)
if dateSource == "lastModified": if dateSource == SettingsValues.Ocr.DateSource.FileLastModified:
datetime = QFileInfo(imagePath).lastModified() datetime = QFileInfo(imagePath).lastModified()
else: else:
datetime = QFileInfo(imagePath).birthTime() datetime = QFileInfo(imagePath).birthTime()

View File

@ -2,9 +2,9 @@ from PySide6.QtCore import QDir, QFileInfo, Qt, Signal, Slot
from PySide6.QtGui import QDragEnterEvent, QDragLeaveEvent, QDropEvent from PySide6.QtGui import QDragEnterEvent, QDragLeaveEvent, QDropEvent
from PySide6.QtWidgets import QFileDialog, QWidget from PySide6.QtWidgets import QFileDialog, QWidget
from core.settings import settings
from ui.designer.components.fileSelector_ui import Ui_FileSelector from ui.designer.components.fileSelector_ui import Ui_FileSelector
from ui.extends.shared.language import LanguageChangeEventFilter from ui.extends.shared.language import LanguageChangeEventFilter
from ui.extends.shared.settings import Settings
class FileSelector(Ui_FileSelector, QWidget): class FileSelector(Ui_FileSelector, QWidget):
@ -122,13 +122,13 @@ class FileSelector(Ui_FileSelector, QWidget):
if self.__selectedFiles: if self.__selectedFiles:
return return
if value := Settings().value(self.settingsKey): if value := settings.value(self.settingsKey):
self.selectFile(value) self.selectFile(value)
Settings().updated.connect(self.settingsUpdated) settings.updated.connect(self.settingsUpdated)
def disconnectSettings(self): def disconnectSettings(self):
Settings().updated.disconnect(self.settingsUpdated) settings.updated.disconnect(self.settingsUpdated)
self.settingsKey = None self.settingsKey = None
def settingsUpdated(self, key: str): def settingsUpdated(self, key: str):
@ -139,4 +139,4 @@ class FileSelector(Ui_FileSelector, QWidget):
if self.__selectedFiles: if self.__selectedFiles:
return return
self.selectFile(Settings().value(self.settingsKey)) self.selectFile(settings.value(self.settingsKey))

View File

@ -1,8 +1,8 @@
from PySide6.QtCore import Signal from PySide6.QtCore import Signal
from PySide6.QtWidgets import QButtonGroup, QDialog from PySide6.QtWidgets import QButtonGroup, QDialog
from core.settings import SettingsKeys, SettingsValues, settings
from ui.designer.components.ocrQueueOptionsDialog_ui import Ui_OcrQueueOptionsDialog from ui.designer.components.ocrQueueOptionsDialog_ui import Ui_OcrQueueOptionsDialog
from ui.extends.shared.settings import Settings
class OcrQueueOptionsDialog(QDialog, Ui_OcrQueueOptionsDialog): class OcrQueueOptionsDialog(QDialog, Ui_OcrQueueOptionsDialog):
@ -29,13 +29,12 @@ class OcrQueueOptionsDialog(QDialog, Ui_OcrQueueOptionsDialog):
self.on_scoreDateSourceButtonGroup_buttonClicked self.on_scoreDateSourceButtonGroup_buttonClicked
) )
self.settings = Settings() settings.updated.connect(self.syncCheckboxesFromSettings)
self.settings.updated.connect(self.syncCheckboxesFromSettings)
self.syncCheckboxesFromSettings() self.syncCheckboxesFromSettings()
def syncCheckboxesFromSettings(self): def syncCheckboxesFromSettings(self):
scoreDateSource = self.settings.scoreDateSource() scoreDateSource = settings.stringValue(SettingsKeys.Ocr.DateSource)
if scoreDateSource == "lastModified": if scoreDateSource == SettingsValues.Ocr.DateSource.FileLastModified:
self.dateUseModifyDateRadioButton.setChecked(True) self.dateUseModifyDateRadioButton.setChecked(True)
else: else:
self.dateUseCreationDateRadioButton.setChecked(True) self.dateUseCreationDateRadioButton.setChecked(True)
@ -43,6 +42,8 @@ class OcrQueueOptionsDialog(QDialog, Ui_OcrQueueOptionsDialog):
def on_scoreDateSourceButtonGroup_buttonClicked(self, button): def on_scoreDateSourceButtonGroup_buttonClicked(self, button):
buttonId = self.scoreDateSourceButtonGroup.id(button) buttonId = self.scoreDateSourceButtonGroup.id(button)
if buttonId == 1: if buttonId == 1:
self.settings.setScoreDateSource("lastModified") value = SettingsValues.Ocr.DateSource.FileLastModified
else: else:
self.settings.setScoreDateSource("birthTime") value = SettingsValues.Ocr.DateSource.FileCreated
settings.setValue(SettingsKeys.Ocr.DateSource, value)

View File

@ -1,6 +1,7 @@
from PySide6.QtCore import QCoreApplication from PySide6.QtCore import QCoreApplication
from PySide6.QtWidgets import QLabel, QPushButton from PySide6.QtWidgets import QLabel, QPushButton
from core.settings import SettingsKeys, settings
from ui.implements.components.fileSelector import FileSelector from ui.implements.components.fileSelector import FileSelector
from ui.implements.settings.settingsBaseWidget import SettingsBaseWidget from ui.implements.settings.settingsBaseWidget import SettingsBaseWidget
@ -14,8 +15,8 @@ class SettingsAndreal(SettingsBaseWidget):
self.andrealFolderValueWidget.setMode( self.andrealFolderValueWidget.setMode(
self.andrealFolderValueWidget.getExistingDirectory self.andrealFolderValueWidget.getExistingDirectory
) )
if self.settings.andrealFolder(): if andrealFolder := settings.stringValue(SettingsKeys.Andreal.Folder):
self.andrealFolderValueWidget.selectFile(self.settings.andrealFolder()) self.andrealFolderValueWidget.selectFile(andrealFolder)
self.andrealFolderValueWidget.filesSelected.connect(self.setAndrealFolder) self.andrealFolderValueWidget.filesSelected.connect(self.setAndrealFolder)
self.andrealFolderResetButton.clicked.connect(self.resetAndrealFolder) self.andrealFolderResetButton.clicked.connect(self.resetAndrealFolder)
self.insertItem( self.insertItem(
@ -25,10 +26,8 @@ class SettingsAndreal(SettingsBaseWidget):
self.andrealFolderResetButton, self.andrealFolderResetButton,
) )
if self.settings.andrealExecutable(): if andrealExecutable := settings.stringValue(SettingsKeys.Andreal.Executable):
self.andrealExecutableValueWidget.selectFile( self.andrealExecutableValueWidget.selectFile(andrealExecutable)
self.settings.andrealExecutable()
)
self.andrealExecutableValueWidget.filesSelected.connect( self.andrealExecutableValueWidget.filesSelected.connect(
self.setAndrealExecutable self.setAndrealExecutable
) )
@ -44,21 +43,21 @@ class SettingsAndreal(SettingsBaseWidget):
selectedFile = self.andrealFolderValueWidget.selectedFiles() selectedFile = self.andrealFolderValueWidget.selectedFiles()
if selectedFile and selectedFile[0]: if selectedFile and selectedFile[0]:
file = selectedFile[0] file = selectedFile[0]
self.settings.setAndrealFolder(file) settings.setValue(SettingsKeys.Andreal.Folder, file)
def resetAndrealFolder(self): def resetAndrealFolder(self):
self.andrealFolderValueWidget.reset() self.andrealFolderValueWidget.reset()
self.settings.resetAndrealFolder() settings.setValue(SettingsKeys.Andreal.Folder, None)
def setAndrealExecutable(self): def setAndrealExecutable(self):
selectedFile = self.andrealExecutableValueWidget.selectedFiles() selectedFile = self.andrealExecutableValueWidget.selectedFiles()
if selectedFile and selectedFile[0]: if selectedFile and selectedFile[0]:
file = selectedFile[0] file = selectedFile[0]
self.settings.setAndrealExecutable(file) settings.setValue(SettingsKeys.Andreal.Executable, file)
def resetAndrealExecutable(self): def resetAndrealExecutable(self):
self.andrealExecutableValueWidget.reset() self.andrealExecutableValueWidget.reset()
self.settings.resetAndrealExecutable() settings.setValue(SettingsKeys.Andreal.Executable, None)
def setupUi(self, *args): def setupUi(self, *args):
self.andrealFolderLabel = QLabel(self) self.andrealFolderLabel = QLabel(self)

View File

@ -1,15 +1,15 @@
from PySide6.QtCore import Qt from PySide6.QtCore import Qt
from PySide6.QtWidgets import QLabel, QPushButton, QWidget from PySide6.QtWidgets import QLabel, QPushButton, QWidget
from core.settings import settings
from ui.designer.settings.settingsBaseWidget_ui import Ui_SettingsBaseWidget from ui.designer.settings.settingsBaseWidget_ui import Ui_SettingsBaseWidget
from ui.extends.shared.language import LanguageChangeEventFilter from ui.extends.shared.language import LanguageChangeEventFilter
from ui.extends.shared.settings import Settings
class SettingsBaseWidget(Ui_SettingsBaseWidget, QWidget): class SettingsBaseWidget(Ui_SettingsBaseWidget, QWidget):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
self.settings = Settings() self.settings = settings
self.languageChangeEventFilter = LanguageChangeEventFilter(self) self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter) self.installEventFilter(self.languageChangeEventFilter)

View File

@ -1,6 +1,4 @@
import sys from PySide6.QtCore import QCoreApplication, QDir, QLocale
from PySide6.QtCore import QCoreApplication, QDir, QLocale, QProcess
from PySide6.QtWidgets import ( from PySide6.QtWidgets import (
QApplication, QApplication,
QCheckBox, QCheckBox,
@ -10,8 +8,8 @@ from PySide6.QtWidgets import (
QPushButton, QPushButton,
) )
from core.settings import SettingsKeys, settings
from ui.extends.shared.language import changeAppLanguage, localeToCode, localeToFullName 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 from ui.implements.settings.settingsBaseWidget import SettingsBaseWidget
@ -33,8 +31,8 @@ class SettingsGeneral(SettingsBaseWidget):
self.languageFollowSystemCheckBox.toggled.connect( self.languageFollowSystemCheckBox.toggled.connect(
self.changeLanguageFollowSystem self.changeLanguageFollowSystem
) )
if self.settings.language(): if language := settings.stringValue(SettingsKeys.General.Language):
locale = QLocale(self.settings.language()) locale = QLocale(language)
index = self.languageValueWidget.findData(locale) index = self.languageValueWidget.findData(locale)
if index > -1: if index > -1:
self.languageValueWidget.setCurrentIndex(index) self.languageValueWidget.setCurrentIndex(index)
@ -51,7 +49,7 @@ class SettingsGeneral(SettingsBaseWidget):
self.insertItem( self.insertItem(
"dbUrl", "dbUrl",
self.dbUrlLabel, self.dbUrlLabel,
QLabel(self.settings.databaseUrl()), QLabel(settings.stringValue(SettingsKeys.General.DatabaseUrl)),
self.dbUrlResetButton, self.dbUrlResetButton,
) )
@ -59,13 +57,13 @@ class SettingsGeneral(SettingsBaseWidget):
locale = self.languageValueWidget.currentData() locale = self.languageValueWidget.currentData()
if locale: if locale:
changeAppLanguage(locale) changeAppLanguage(locale)
self.settings.setLanguage(localeToCode(locale)) settings.setValue(SettingsKeys.General.Language, localeToCode(locale))
def changeLanguageFollowSystem(self): def changeLanguageFollowSystem(self):
followSystem = self.languageFollowSystemCheckBox.isChecked() followSystem = self.languageFollowSystemCheckBox.isChecked()
self.languageValueWidget.setCurrentIndex(-1) self.languageValueWidget.setCurrentIndex(-1)
if followSystem: if followSystem:
self.settings.remove(LANGUAGE) settings.remove(SettingsKeys.General.Language)
changeAppLanguage(QLocale.system()) changeAppLanguage(QLocale.system())
self.languageValueWidget.setEnabled(False) self.languageValueWidget.setEnabled(False)
else: else:
@ -80,7 +78,7 @@ class SettingsGeneral(SettingsBaseWidget):
QMessageBox.StandardButton.No, QMessageBox.StandardButton.No,
) )
if userConfirm == QMessageBox.StandardButton.Yes: if userConfirm == QMessageBox.StandardButton.Yes:
self.settings.remove(DATABASE_URL) settings.remove(SettingsKeys.General.DatabaseUrl)
QApplication.instance().quit() QApplication.instance().quit()
def setupUi(self, *args): def setupUi(self, *args):
@ -99,10 +97,10 @@ class SettingsGeneral(SettingsBaseWidget):
# fmt: off # fmt: off
self.setTitle(QCoreApplication.translate("Settings", "general.title")) self.setTitle(QCoreApplication.translate("Settings", "general.title"))
self.languageLabel.setText(QCoreApplication.translate("Settings", "general.language.label")) self.languageLabel.setText(QCoreApplication.translate("Settings", "general.language.label"))
self.languageFollowSystemCheckBox.setText(QCoreApplication.translate("Settings", "general.language.followSystem")) self.languageFollowSystemCheckBox.setText(QCoreApplication.translate("Settings", "general.language.followSystem"))
self.dbUrlLabel.setText(QCoreApplication.translate("Settings", "general.dbUrl.label")) self.dbUrlLabel.setText(QCoreApplication.translate("Settings", "general.dbUrl.label"))
self.dbUrlResetButton.setText(QCoreApplication.translate("Settings", "resetButton")) self.dbUrlResetButton.setText(QCoreApplication.translate("Settings", "resetButton"))
# fmt: on # fmt: on

View File

@ -1,6 +1,7 @@
from PySide6.QtCore import QCoreApplication from PySide6.QtCore import QCoreApplication
from PySide6.QtWidgets import QLabel, QPushButton from PySide6.QtWidgets import QLabel, QPushButton
from core.settings import SettingsKeys, settings
from ui.implements.components.fileSelector import FileSelector from ui.implements.components.fileSelector import FileSelector
from ui.implements.settings.settingsBaseWidget import SettingsBaseWidget from ui.implements.settings.settingsBaseWidget import SettingsBaseWidget
@ -11,8 +12,8 @@ class SettingsOcr(SettingsBaseWidget):
self.setupUi(self) self.setupUi(self)
if self.settings.knnModelFile(): if knnModelFile := settings.stringValue(SettingsKeys.Ocr.KnnModelFile):
self.knnModelFileValueWidget.selectFile(self.settings.knnModelFile()) self.knnModelFileValueWidget.selectFile(knnModelFile)
self.knnModelFileValueWidget.filesSelected.connect(self.setKnnModelFile) self.knnModelFileValueWidget.filesSelected.connect(self.setKnnModelFile)
self.knnModelFileResetButton.clicked.connect(self.resetKnnModelFile) self.knnModelFileResetButton.clicked.connect(self.resetKnnModelFile)
self.insertItem( self.insertItem(
@ -22,8 +23,8 @@ class SettingsOcr(SettingsBaseWidget):
self.knnModelFileResetButton, self.knnModelFileResetButton,
) )
if self.settings.b30KnnModelFile(): if b30KnnModelFile := settings.stringValue(SettingsKeys.Ocr.B30KnnModelFile):
self.b30KnnModelFileValueWidget.selectFile(self.settings.b30KnnModelFile()) self.b30KnnModelFileValueWidget.selectFile(b30KnnModelFile)
self.b30KnnModelFileValueWidget.filesSelected.connect(self.setB30KnnModelFile) self.b30KnnModelFileValueWidget.filesSelected.connect(self.setB30KnnModelFile)
self.b30KnnModelFileResetButton.clicked.connect(self.resetB30KnnModelFile) self.b30KnnModelFileResetButton.clicked.connect(self.resetB30KnnModelFile)
self.insertItem( self.insertItem(
@ -33,10 +34,10 @@ class SettingsOcr(SettingsBaseWidget):
self.b30KnnModelFileResetButton, self.b30KnnModelFileResetButton,
) )
if self.settings.phashDatabaseFile(): if phashDatabaseFile := settings.stringValue(
self.phashDatabaseFileValueWidget.selectFile( SettingsKeys.Ocr.PhashDatabaseFile
self.settings.phashDatabaseFile() ):
) self.phashDatabaseFileValueWidget.selectFile(phashDatabaseFile)
self.phashDatabaseFileValueWidget.filesSelected.connect( self.phashDatabaseFileValueWidget.filesSelected.connect(
self.setPHashDatabaseFile self.setPHashDatabaseFile
) )
@ -52,31 +53,31 @@ class SettingsOcr(SettingsBaseWidget):
selectedFile = self.knnModelFileValueWidget.selectedFiles() selectedFile = self.knnModelFileValueWidget.selectedFiles()
if selectedFile and selectedFile[0]: if selectedFile and selectedFile[0]:
file = selectedFile[0] file = selectedFile[0]
self.settings.setKnnModelFile(file) settings.setValue(SettingsKeys.Ocr.KnnModelFile, file)
def resetKnnModelFile(self): def resetKnnModelFile(self):
self.knnModelFileValueWidget.reset() self.knnModelFileValueWidget.reset()
self.settings.resetKnnModelFile() settings.setValue(SettingsKeys.Ocr.KnnModelFile, None)
def setB30KnnModelFile(self): def setB30KnnModelFile(self):
selectedFile = self.b30KnnModelFileValueWidget.selectedFiles() selectedFile = self.b30KnnModelFileValueWidget.selectedFiles()
if selectedFile and selectedFile[0]: if selectedFile and selectedFile[0]:
file = selectedFile[0] file = selectedFile[0]
self.settings.setB30KnnModelFile(file) settings.setValue(SettingsKeys.Ocr.B30KnnModelFile, file)
def resetB30KnnModelFile(self): def resetB30KnnModelFile(self):
self.b30KnnModelFileValueWidget.reset() self.b30KnnModelFileValueWidget.reset()
self.settings.resetB30KnnModelFile() settings.setValue(SettingsKeys.Ocr.B30KnnModelFile, None)
def setPHashDatabaseFile(self): def setPHashDatabaseFile(self):
selectedFile = self.phashDatabaseFileValueWidget.selectedFiles() selectedFile = self.phashDatabaseFileValueWidget.selectedFiles()
if selectedFile and selectedFile[0]: if selectedFile and selectedFile[0]:
file = selectedFile[0] file = selectedFile[0]
self.settings.setPHashDatabaseFile(file) settings.setValue(SettingsKeys.Ocr.PhashDatabaseFile, file)
def resetPHashDatabaseFile(self): def resetPHashDatabaseFile(self):
self.phashDatabaseFileValueWidget.reset() self.phashDatabaseFileValueWidget.reset()
self.settings.resetPHashDatabaseFile() settings.setValue(SettingsKeys.Ocr.PhashDatabaseFile, None)
def setupUi(self, *args): def setupUi(self, *args):
self.knnModelFileLabel = QLabel(self) self.knnModelFileLabel = QLabel(self)

View File

@ -9,6 +9,7 @@ from PIL import Image
from PySide6.QtCore import Signal, Slot from PySide6.QtCore import Signal, Slot
from PySide6.QtWidgets import QFileDialog, QMessageBox, QWidget 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.designer.tabs.tabOcr.tabOcr_B30_ui import Ui_TabOcr_B30
from ui.extends.components.ocrQueue import OcrQueueModel from ui.extends.components.ocrQueue import OcrQueueModel
from ui.extends.ocr.dependencies import ( from ui.extends.ocr.dependencies import (
@ -16,11 +17,6 @@ from ui.extends.ocr.dependencies import (
getPhashDatabaseStatusText, getPhashDatabaseStatusText,
) )
from ui.extends.shared.language import LanguageChangeEventFilter 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 from ui.extends.tabs.tabOcr.tabOcr_B30 import ChieriV4OcrRunnable, b30ResultToScore
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -55,9 +51,15 @@ class TabOcr_B30(Ui_TabOcr_B30, QWidget):
self.ocr = None self.ocr = None
logger.info("Applying settings...") logger.info("Applying settings...")
self.dependencies_knnModelSelector.connectSettings(KNN_MODEL_FILE) self.dependencies_knnModelSelector.connectSettings(
self.dependencies_b30KnnModelSelector.connectSettings(B30_KNN_MODEL_FILE) SettingsKeys.Ocr.KnnModelFile
self.dependencies_phashDatabaseSelector.connectSettings(PHASH_DATABASE_FILE) )
self.dependencies_b30KnnModelSelector.connectSettings(
SettingsKeys.Ocr.B30KnnModelFile
)
self.dependencies_phashDatabaseSelector.connectSettings(
SettingsKeys.Ocr.PhashDatabaseFile
)
self.ocrQueueModel = OcrQueueModel(self) self.ocrQueueModel = OcrQueueModel(self)
self.ocrQueue.setModel(self.ocrQueueModel) self.ocrQueue.setModel(self.ocrQueueModel)

View File

@ -11,10 +11,10 @@ from arcaea_offline_ocr.phash_db import ImagePhashDatabase
from PySide6.QtCore import Slot from PySide6.QtCore import Slot
from PySide6.QtWidgets import QApplication, QFileDialog, QMessageBox, QWidget 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.designer.tabs.tabOcr.tabOcr_Device_ui import Ui_TabOcr_Device
from ui.extends.components.ocrQueue import OcrQueueModel from ui.extends.components.ocrQueue import OcrQueueModel
from ui.extends.shared.language import LanguageChangeEventFilter 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 from ui.extends.tabs.tabOcr.tabOcr_Device import ScoreConverter, TabDeviceOcrRunnable
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -54,8 +54,12 @@ class TabOcr_Device(Ui_TabOcr_Device, QWidget):
) )
logger.info("Applying settings...") logger.info("Applying settings...")
self.dependencies_knnModelSelector.connectSettings(KNN_MODEL_FILE) self.dependencies_knnModelSelector.connectSettings(
self.dependencies_phashDatabaseSelector.connectSettings(PHASH_DATABASE_FILE) SettingsKeys.Ocr.KnnModelFile
)
self.dependencies_phashDatabaseSelector.connectSettings(
SettingsKeys.Ocr.PhashDatabaseFile
)
self.options_usePresetCheckBox.setChecked(True) self.options_usePresetCheckBox.setChecked(True)
self.options_usePresetCheckBox.setEnabled(False) self.options_usePresetCheckBox.setEnabled(False)

View File

@ -11,9 +11,9 @@ from PySide6.QtCore import QCoreApplication, QDir, QFileInfo, Qt, Slot
from PySide6.QtGui import QGuiApplication, QImage, QPainter, QPaintEvent, QPixmap from PySide6.QtGui import QGuiApplication, QImage, QPainter, QPaintEvent, QPixmap
from PySide6.QtWidgets import QButtonGroup, QFileDialog, QLabel, QMessageBox, QWidget 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.designer.tabs.tabTools.tabTools_Andreal_ui import Ui_TabTools_Andreal
from ui.extends.shared.language import LanguageChangeEventFilter 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.extends.tabs.tabTools.tabTools_Andreal import AndrealHelper
from ui.implements.components.chartSelector import ChartSelector from ui.implements.components.chartSelector import ChartSelector
from ui.implements.components.songIdSelector import SongIdSelectorMode 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.andrealFolderSelector.filesSelected.connect(self.setHelperPaths)
self.andrealExecutableSelector.filesSelected.connect(self.setHelperPaths) self.andrealExecutableSelector.filesSelected.connect(self.setHelperPaths)
self.andrealFolderSelector.connectSettings(ANDREAL_FOLDER) self.andrealFolderSelector.connectSettings(SettingsKeys.Andreal.Folder)
self.andrealExecutableSelector.connectSettings(ANDREAL_EXECUTABLE) self.andrealExecutableSelector.connectSettings(SettingsKeys.Andreal.Executable)
self.generatePreviewButton.clicked.connect(self.requestPreview) self.generatePreviewButton.clicked.connect(self.requestPreview)
self.generateImageButton.clicked.connect(self.requestGenerate) self.generateImageButton.clicked.connect(self.requestGenerate)
@ -134,10 +134,8 @@ class TabTools_Andreal(Ui_TabTools_Andreal, QWidget):
QMessageBox.information( QMessageBox.information(
self, self,
None, None,
# fmt: off
QCoreApplication.translate("TabTools_Andreal", "imageWhatIsThisDialog.description"), QCoreApplication.translate("TabTools_Andreal", "imageWhatIsThisDialog.description"),
# fmt: on ) # fmt: skip
)
def imageFormat(self): def imageFormat(self):
buttonId = self.imageFormatButtonGroup.checkedId() buttonId = self.imageFormatButtonGroup.checkedId()

View File

@ -6,8 +6,8 @@ from arcaea_offline.database import Database
from PySide6.QtCore import QCoreApplication, QDir, QFileInfo, QSysInfo, Qt, QUrl, Slot from PySide6.QtCore import QCoreApplication, QDir, QFileInfo, QSysInfo, Qt, QUrl, Slot
from PySide6.QtWidgets import QDialog, QMessageBox from PySide6.QtWidgets import QDialog, QMessageBox
from core.settings import SettingsKeys, settings
from ui.extends.shared.database import create_engine from ui.extends.shared.database import create_engine
from ui.extends.shared.settings import Settings
from .databaseChecker_ui import Ui_DatabaseChecker from .databaseChecker_ui import Ui_DatabaseChecker
@ -29,8 +29,7 @@ class DatabaseChecker(Ui_DatabaseChecker, QDialog):
self.dbDirSelector.setMode(self.dbDirSelector.getExistingDirectory) self.dbDirSelector.setMode(self.dbDirSelector.getExistingDirectory)
self.confirmDbByExistingSettings = False self.confirmDbByExistingSettings = False
self.settings = Settings(self) if dbUrlString := settings.stringValue(SettingsKeys.General.DatabaseUrl):
if dbUrlString := self.settings.databaseUrl():
dbFileUrl = QUrl(dbUrlString.replace("sqlite://", "file://")) dbFileUrl = QUrl(dbUrlString.replace("sqlite://", "file://"))
dbFileInfo = QFileInfo(dbFileUrl.toLocalFile()) dbFileInfo = QFileInfo(dbFileUrl.toLocalFile())
if dbFileInfo.exists(): if dbFileInfo.exists():
@ -45,6 +44,9 @@ class DatabaseChecker(Ui_DatabaseChecker, QDialog):
self.dbDirSelector.selectFile(QDir.currentPath()) self.dbDirSelector.selectFile(QDir.currentPath())
self.dbFilenameLineEdit.setText("arcaea_offline.db") self.dbFilenameLineEdit.setText("arcaea_offline.db")
def writeDatabaseUrlToSettings(self, databaseUrl: str):
settings.setValue(SettingsKeys.General.DatabaseUrl, databaseUrl)
def dbPath(self): def dbPath(self):
return QDir(self.dbDirSelector.selectedFiles()[0]) return QDir(self.dbDirSelector.selectedFiles()[0])
@ -79,7 +81,7 @@ class DatabaseChecker(Ui_DatabaseChecker, QDialog):
db = Database(create_engine(dbSqliteUrl)) db = Database(create_engine(dbSqliteUrl))
if db.check_init(): if db.check_init():
flags |= DatabaseCheckerResult.Initted flags |= DatabaseCheckerResult.Initted
self.settings.setDatabaseUrl(self.dbSqliteUrl().toString()) self.writeDatabaseUrlToSettings(self.dbSqliteUrl().toString())
return flags return flags
@ -108,20 +110,18 @@ class DatabaseChecker(Ui_DatabaseChecker, QDialog):
@Slot() @Slot()
def on_confirmDbPathButton_clicked(self): def on_confirmDbPathButton_clicked(self):
dbSqliteUrl = self.dbSqliteUrl() dbSqliteUrl = self.dbSqliteUrl()
self.settings.setDatabaseUrl(dbSqliteUrl.toString()) self.writeDatabaseUrlToSettings(dbSqliteUrl.toString())
result = self.confirmDb() result = self.confirmDb()
if result & DatabaseCheckerResult.Initted: if result & DatabaseCheckerResult.Initted:
if not self.confirmDbByExistingSettings: if not self.confirmDbByExistingSettings:
self.settings.setDatabaseUrl(dbSqliteUrl.toString()) self.writeDatabaseUrlToSettings(dbSqliteUrl.toString())
elif result & DatabaseCheckerResult.FileExist: elif result & DatabaseCheckerResult.FileExist:
confirm_try_init = QMessageBox.question( confirm_try_init = QMessageBox.question(
self, self,
None, None,
# fmt: off
QCoreApplication.translate("DatabaseChecker", "dialog.tryInitExistingDatabase"), QCoreApplication.translate("DatabaseChecker", "dialog.tryInitExistingDatabase"),
# fmt: on ) # fmt: skip
)
if confirm_try_init == QMessageBox.StandardButton.Yes: if confirm_try_init == QMessageBox.StandardButton.Yes:
try: try:
Database().init(checkfirst=True) Database().init(checkfirst=True)
@ -134,10 +134,8 @@ class DatabaseChecker(Ui_DatabaseChecker, QDialog):
confirm_new_database = QMessageBox.question( confirm_new_database = QMessageBox.question(
self, self,
None, None,
# fmt: off
QCoreApplication.translate("DatabaseChecker", "dialog.confirmNewDatabase"), QCoreApplication.translate("DatabaseChecker", "dialog.confirmNewDatabase"),
# fmt: on ) # fmt: skip
)
if confirm_new_database == QMessageBox.StandardButton.Yes: if confirm_new_database == QMessageBox.StandardButton.Yes:
db = Database(create_engine(dbSqliteUrl)) db = Database(create_engine(dbSqliteUrl))
db.init() db.init()