170 lines
5.9 KiB
Python
170 lines
5.9 KiB
Python
import json
|
|
import os
|
|
import re
|
|
from typing import Any, Dict, List, Optional, Self, Type, cast
|
|
|
|
from PyQt6.QtCore import (
|
|
QCoreApplication,
|
|
QLocale,
|
|
QResource,
|
|
Qt,
|
|
QTranslator,
|
|
pyqtSlot,
|
|
)
|
|
from PyQt6.QtMultimedia import QMediaDevices
|
|
from PyQt6.QtWidgets import QAbstractItemView, QDialog, QListWidgetItem, QWidget
|
|
|
|
from ui.Preferences import Ui_Preferences
|
|
|
|
|
|
class Preferences(QDialog, Ui_Preferences):
|
|
translator: Optional[QTranslator]
|
|
_instance = None
|
|
preferences: Dict[str, str | List[str]]
|
|
|
|
def __new__(cls: Type[Self]) -> Self:
|
|
if cls._instance:
|
|
return cls._instance
|
|
cls._instance = super(Preferences, cls).__new__(cls)
|
|
return cls._instance
|
|
|
|
@pyqtSlot(int)
|
|
def done(self, r: int) -> None:
|
|
self.hide()
|
|
super().done(r)
|
|
return
|
|
|
|
@pyqtSlot()
|
|
def exec(self) -> int:
|
|
self.show()
|
|
return super().exec()
|
|
|
|
@pyqtSlot()
|
|
def open(self) -> None:
|
|
self.show()
|
|
super().open()
|
|
return
|
|
|
|
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
super(Preferences, self).__init__(*args, **kwargs)
|
|
self.setupUi(self)
|
|
self.hide()
|
|
#
|
|
# Overrides
|
|
#
|
|
self.alertList.setSelectionMode(
|
|
QAbstractItemView.SelectionMode.MultiSelection
|
|
)
|
|
self.playerList.setSelectionMode(
|
|
QAbstractItemView.SelectionMode.MultiSelection
|
|
)
|
|
self.readerCombo.setEditable(False)
|
|
self.phoneticsCombo.setEditable(False)
|
|
#
|
|
# End OverRides
|
|
#
|
|
for index, output in enumerate(QMediaDevices.audioOutputs()):
|
|
identifier = output.id().data().decode("utf-8")
|
|
description = output.description()
|
|
self.alertList.addItem(description)
|
|
self.playerList.addItem(description)
|
|
resource = QResource("/translate")
|
|
translator = QTranslator()
|
|
for child in resource.children():
|
|
fn = f":/translate/{child}"
|
|
if translator.load(fn):
|
|
locale = QLocale(translator.language())
|
|
lang_code = locale.language()
|
|
language = QLocale.languageToString(lang_code)
|
|
self.languageCombo.addItem(language, translator.language())
|
|
self.setCurrent()
|
|
return
|
|
|
|
def setCurrent(self) -> None:
|
|
if os.path.exists("preferences.json"):
|
|
with open("preferences.json", "r") as f:
|
|
self.preferences = json.load(f)
|
|
else:
|
|
self.preferences = {
|
|
"readerFont": "OpenDyslexic",
|
|
"phoneticFont": "Gentium",
|
|
"alertOutputs": ["default"],
|
|
"playerOutputs": ["Feed for virtual microphone"],
|
|
"language": "pt",
|
|
}
|
|
for output in self.preferences["alertOutputs"]:
|
|
if output == "default":
|
|
output = QMediaDevices.defaultAudioOutput().description()
|
|
for item in self.alertList.findItems(
|
|
output, Qt.MatchFlag.MatchExactly
|
|
):
|
|
item.setSelected(True)
|
|
for output in self.preferences["playerOutputs"]:
|
|
if output == "default":
|
|
output = QMediaDevices.defaultAudioOutput().description()
|
|
for item in self.playerList.findItems(
|
|
output, Qt.MatchFlag.MatchExactly
|
|
):
|
|
item.setSelected(True)
|
|
index = self.languageCombo.findData(self.preferences["language"])
|
|
if index >= 0:
|
|
self.languageCombo.setCurrentIndex(index)
|
|
self.translator = QTranslator()
|
|
if self.translator.load(
|
|
f":/translate/esl_reader_{self.preferences['language']}"
|
|
):
|
|
assert self.translator is not None
|
|
QCoreApplication.installTranslator(self.translator)
|
|
else:
|
|
self.translator = None
|
|
index = self.readerCombo.findText(self.preferences["readerFont"])
|
|
if index >= 0:
|
|
self.readerCombo.setCurrentIndex(index)
|
|
index = self.phoneticsCombo.findText(self.preferences["phoneticFont"])
|
|
if index >= 0:
|
|
self.phoneticsCombo.setCurrentIndex(index)
|
|
return
|
|
|
|
def get(
|
|
self, name: Optional[str] = None
|
|
) -> str | List[str] | Dict[str, str | List[str]]:
|
|
if not name:
|
|
return self.preferences
|
|
return self.preferences[name]
|
|
|
|
def accept(self) -> None:
|
|
self.preferences["readerFont"] = self.readerCombo.currentFont().family()
|
|
self.preferences[
|
|
"phoneticFont"
|
|
] = self.phoneticsCombo.currentFont().family()
|
|
self.preferences["language"] = self.languageCombo.currentData()
|
|
self.preferences["alertOutputs"] = [
|
|
x.data(Qt.ItemDataRole.DisplayRole)
|
|
for x in self.alertList.selectedItems()
|
|
]
|
|
self.preferences["playerOutputs"] = [
|
|
x.data(Qt.ItemDataRole.DisplayRole)
|
|
for x in self.playerList.selectedItems()
|
|
]
|
|
with open("preferences.json", "w") as f:
|
|
json.dump(self.preferences, f, indent=2)
|
|
if self.translator:
|
|
if self.translator.language() != self.preferences["language"]:
|
|
full_code: str = cast(str, self.preferences["language"])
|
|
locale = QLocale(full_code)
|
|
language = locale.language()
|
|
code = QLocale.languageToCode(
|
|
language, QLocale.LanguageCodeType.ISO639Part1
|
|
)
|
|
print(language, code)
|
|
fn = f":/translate/esl_reader_{code}.qm"
|
|
translator = QTranslator()
|
|
if translator.load(fn):
|
|
QCoreApplication.removeTranslator(self.translator)
|
|
self.translator = translator
|
|
QCoreApplication.installTranslator(self.translator)
|
|
else:
|
|
print(self.tr("Unable to load translation file ") + f"{fn}")
|
|
super().accept()
|
|
return
|