Files
esl-reader/lib/preferences.py
Christopher T. Johnson 793d758377 I18N Code Work done.
2024-02-14 10:02:27 -05:00

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