diff --git a/lib/__init__.py b/lib/__init__.py
index 3056e3a..8cbe3d7 100644
--- a/lib/__init__.py
+++ b/lib/__init__.py
@@ -2,4 +2,3 @@ from .books import Book
from .person import PersonDialog
from .read import EditDialog
from .session import SessionDialog
-from .sounds import SoundOff
diff --git a/lib/preferences.py b/lib/preferences.py
new file mode 100644
index 0000000..0e2db20
--- /dev/null
+++ b/lib/preferences.py
@@ -0,0 +1,95 @@
+import json
+import os
+from PyQt6.QtCore import Qt, pyqtSlot
+from PyQt6.QtWidgets import QDialog, QListWidgetItem, QAbstractItemView
+from PyQt6.QtMultimedia import QMediaDevices
+from ui.Preferences import Ui_Dialog
+
+class Preferences(QDialog, Ui_Dialog):
+ _instance = None
+ def __new__(cls):
+ if cls._instance:
+ return cls._instance
+ cls._instance = super(Preferences, cls).__new__(cls)
+ return cls._instance
+ @pyqtSlot(int)
+ def done(self,r):
+ self.hide()
+ super().done(r)
+ return
+ @pyqtSlot()
+ def exec(self):
+ self.show()
+ super().exec()
+ return
+ @pyqtSlot()
+ def open(self):
+ self.show()
+ super().open()
+ return
+
+ def __init__(self, *args, **kwargs):
+ 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)
+ self.setCurrent()
+ return
+
+ def setCurrent(self):
+ 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' ]
+ }
+ 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.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:str =None):
+ if not name:
+ return self.preferences
+ return self.preferences[name]
+
+ def accept(self):
+ self.preferences['readerFont'] = self.readerCombo.currentFont().family()
+ self.preferences['phoneticFont'] =self.phoneticsCombo.currentFont().family()
+ 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)
+ super().accept()
+ return
diff --git a/lib/read.py b/lib/read.py
index f17d455..d45da67 100644
--- a/lib/read.py
+++ b/lib/read.py
@@ -18,7 +18,6 @@ from PyQt6.QtCore import (
from PyQt6.QtGui import (
QBrush,
QColor,
- QFont,
QKeyEvent,
QMouseEvent,
QPainter,
@@ -35,21 +34,32 @@ from PyQt6.QtWidgets import QDialog, QPushButton
from main import query_error
from ui.EditDialog import Ui_Dialog
-
+from lib.preferences import Preferences
+from lib.sounds import SoundOff
class EditDialog(QDialog, Ui_Dialog):
+ playSound = pyqtSignal(str)
block: int
paragraphs = True
sessionSignal = pyqtSignal()
displayedWord = pyqtSignal(int)
newParagraph = pyqtSignal(int, int)
-
+
def __init__(self, parent, session, person_id: int) -> None:
self.session = session
super(EditDialog, self).__init__(parent)
- print(self.parent())
self.person_id = person_id
+ self.preferences = Preferences().get()
+ self.sound = SoundOff()
styleSheet = QResource(":/display.css").data().decode("utf-8")
+ print(styleSheet)
+ styleSheet = styleSheet.replace(
+ '{readerFont}',self.preferences['readerFont']
+ )
+ styleSheet = styleSheet.replace(
+ '{phoneticFont}',self.preferences['phoneticFont']
+ )
+ print(styleSheet)
self.setupUi(self)
#
# Override UI
@@ -75,8 +85,6 @@ class EditDialog(QDialog, Ui_Dialog):
self.scrollBtn.clicked.connect(self.scrollAction)
self.nextBtn.clicked.connect(self.nextAction)
self.prevBtn.clicked.connect(self.prevAction)
- # self.sessionSignal.connect(self.session.timerAction)
- # self.sessionBtn.clicked.connect(self.sessionAction)
self.sessionBtn.clicked.connect(self.session.timerAction)
self.paraEdit.verticalScrollBar().valueChanged.connect(self.scrollSlot)
self.defEdit.selectionChanged.connect(self.recursiveDef)
@@ -85,6 +93,8 @@ class EditDialog(QDialog, Ui_Dialog):
#
self.displayedWord.connect(self.session.addWord)
self.newParagraph.connect(self.session.addBlock)
+ self.playSound.connect(self.sound.playSound)
+ #self.alert.connect(self.sound.alert)
return
#
@@ -161,14 +171,14 @@ class EditDialog(QDialog, Ui_Dialog):
self.phonetics = data["phonetics"]
else:
self.phonetics = None
- print("Checking for phonetics")
if not self.phonetics:
return
- print("Looking for audio")
+ print("Searching for audio file")
for entry in self.phonetics:
if len(entry["audio"]) > 0:
# self.parent().playAlert.emit()
- self.parent().playSound.emit(entry["audio"])
+ print(f"playing {entry['audio']}")
+ self.playSound.emit(entry["audio"])
return
@pyqtSlot()
diff --git a/lib/session.py b/lib/session.py
index d3b0642..88a086f 100644
--- a/lib/session.py
+++ b/lib/session.py
@@ -114,7 +114,7 @@ class SessionDialog(QDialog, Ui_Dialog):
query = QSqlQuery()
query.prepare(
"UPDATE sessions "
- "SET start=:start , SET stop=:stop, SET notes=:notes "
+ "SET start=:start, stop=:stop, notes=:notes "
"WHERE sesion_id = :session_id"
)
query.bindValue(":session_id", self.session_id)
diff --git a/lib/sounds.py b/lib/sounds.py
index bd37cfe..a891153 100644
--- a/lib/sounds.py
+++ b/lib/sounds.py
@@ -11,6 +11,13 @@ from PyQt6.QtMultimedia import (
class SoundOff(QObject):
+ _instance = None
+ def __new__(cls):
+ if cls._instance:
+ return cls._instance
+ cls._instance = super(SoundOff, cls).__new__(cls)
+ return cls._instance
+
def __init__(self):
super().__init__()
#
@@ -95,7 +102,6 @@ class SoundOff(QObject):
self.localPlayer.play()
if not self.virtualDevice:
return
- return
self.virtualPlayer.setSource(src)
self.virtualPlayer.setPosition(0)
if not self.virtualPlayer.audioOutput():
diff --git a/main.py b/main.py
index 48f59b2..6024138 100755
--- a/main.py
+++ b/main.py
@@ -44,6 +44,7 @@ from PyQt6.QtWidgets import (
)
from lib import *
+from lib.preferences import Preferences
from ui.MainWindow import Ui_MainWindow
@@ -60,8 +61,6 @@ def query_error(query: QSqlQuery) -> None:
class MainWindow(QMainWindow, Ui_MainWindow):
- playAlert = pyqtSignal()
- playSound = pyqtSignal(str)
def __init__(self) -> None:
super(MainWindow, self).__init__()
@@ -73,8 +72,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
os.path.join(os.path.dirname(__file__), "ui/resources.rcc"), "/"
):
raise Exception("Unable to register resources.rcc")
- self.soundOff = SoundOff()
-
+
model = QSqlQueryModel()
query = QSqlQuery("SELECT * FROM people ORDER BY name")
model.setQuery(query)
@@ -86,23 +84,28 @@ class MainWindow(QMainWindow, Ui_MainWindow):
#
# Action Connections
#
- self.actionQuit.triggered.connect(self.close) # Y
- self.actionAddBook.triggered.connect(self.addBook) # Y
- self.actionEditBook.triggered.connect(self.editBook) # Y
- self.actionRead.triggered.connect(self.readBook) # Y
+ self.actionQuit.triggered.connect(self.close)
+ self.actionAddBook.triggered.connect(self.addBook)
+ self.actionEditBook.triggered.connect(self.editBook)
+ self.actionRead.triggered.connect(self.readBook)
self.actionRead.enabledChanged.connect(self.readBtn.setEnabled)
- self.actionAddPerson.triggered.connect(self.addPerson) # Y
- self.actionEditPerson.triggered.connect(self.editPerson) # Y
+ self.actionAddPerson.triggered.connect(self.addPerson)
+ self.actionEditPerson.triggered.connect(self.editPerson)
self.actionEditPerson.enabledChanged.connect(
self.editBtn.setEnabled
- ) # Y
- self.peopleView.doubleClicked.connect(self.editPerson) # Y
- self.peopleView.clicked.connect(self.selectedPerson) # Y
- self.playAlert.connect(self.soundOff.alert)
- self.playSound.connect(self.soundOff.playSound)
+ )
+ self.actionPreferences.triggered.connect(self.editPreferences)
+ self.peopleView.doubleClicked.connect(self.editPerson)
+ self.peopleView.clicked.connect(self.selectedPerson)
self.show()
return
+ @pyqtSlot()
+ def editPreferences(self):
+ dlg = Preferences()
+ dlg.exec()
+ return
+
@pyqtSlot(QModelIndex)
def selectedPerson(self, index: QModelIndex) -> None:
person_id = index.siblingAtColumn(0).data()
diff --git a/ui/MainWindow.py b/ui/MainWindow.py
index c910b0b..6d41ceb 100644
--- a/ui/MainWindow.py
+++ b/ui/MainWindow.py
@@ -46,7 +46,7 @@ class Ui_MainWindow(object):
self.horizontalLayout.addWidget(self.widget)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(parent=MainWindow)
- self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 32))
+ self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 24))
self.menubar.setObjectName("menubar")
self.menuFile = QtWidgets.QMenu(parent=self.menubar)
self.menuFile.setObjectName("menuFile")
@@ -72,6 +72,8 @@ class Ui_MainWindow(object):
self.actionEditPerson.setObjectName("actionEditPerson")
self.actionRead = QtGui.QAction(parent=MainWindow)
self.actionRead.setObjectName("actionRead")
+ self.actionPreferences = QtGui.QAction(parent=MainWindow)
+ self.actionPreferences.setObjectName("actionPreferences")
self.menuFile.addAction(self.actionQuit)
self.menuBooks_2.addAction(self.actionAddBook)
self.menuBooks_2.addAction(self.actionEditBook)
@@ -79,6 +81,7 @@ class Ui_MainWindow(object):
self.menuPeople.addAction(self.actionEditPerson)
self.menuBooks.addAction(self.menuBooks_2.menuAction())
self.menuBooks.addAction(self.menuPeople.menuAction())
+ self.menuBooks.addAction(self.actionPreferences)
self.menubar.addAction(self.menuFile.menuAction())
self.menubar.addAction(self.menuBooks.menuAction())
@@ -111,3 +114,4 @@ class Ui_MainWindow(object):
self.actionEditPerson.setToolTip(_translate("MainWindow", "Edit A Person"))
self.actionRead.setText(_translate("MainWindow", "Read"))
self.actionRead.setToolTip(_translate("MainWindow", "Read Book"))
+ self.actionPreferences.setText(_translate("MainWindow", "Preferences"))
diff --git a/ui/MainWindow.ui b/ui/MainWindow.ui
index af4e159..933d7a1 100644
--- a/ui/MainWindow.ui
+++ b/ui/MainWindow.ui
@@ -80,7 +80,7 @@
0
0
800
- 32
+ 24
+
@@ -159,6 +160,11 @@
Read Book
+
+
+ Preferences
+
+
diff --git a/ui/Preferences.py b/ui/Preferences.py
new file mode 100644
index 0000000..2dd6da4
--- /dev/null
+++ b/ui/Preferences.py
@@ -0,0 +1,62 @@
+# Form implementation generated from reading ui file 'ui/Preferences.ui'
+#
+# Created by: PyQt6 UI code generator 6.6.0
+#
+# WARNING: Any manual changes made to this file will be lost when pyuic6 is
+# run again. Do not edit this file unless you know what you are doing.
+
+
+from PyQt6 import QtCore, QtGui, QtWidgets
+
+
+class Ui_Dialog(object):
+ def setupUi(self, Dialog):
+ Dialog.setObjectName("Dialog")
+ Dialog.resize(601, 265)
+ self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.formLayout = QtWidgets.QFormLayout()
+ self.formLayout.setObjectName("formLayout")
+ self.label = QtWidgets.QLabel(parent=Dialog)
+ self.label.setObjectName("label")
+ self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label)
+ self.readerCombo = QtWidgets.QFontComboBox(parent=Dialog)
+ self.readerCombo.setObjectName("readerCombo")
+ self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.readerCombo)
+ self.label_2 = QtWidgets.QLabel(parent=Dialog)
+ self.label_2.setObjectName("label_2")
+ self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_2)
+ self.phoneticsCombo = QtWidgets.QFontComboBox(parent=Dialog)
+ self.phoneticsCombo.setObjectName("phoneticsCombo")
+ self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.phoneticsCombo)
+ self.label_3 = QtWidgets.QLabel(parent=Dialog)
+ self.label_3.setObjectName("label_3")
+ self.formLayout.setWidget(2, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_3)
+ self.alertList = QtWidgets.QListWidget(parent=Dialog)
+ self.alertList.setObjectName("alertList")
+ self.formLayout.setWidget(2, QtWidgets.QFormLayout.ItemRole.FieldRole, self.alertList)
+ self.label_4 = QtWidgets.QLabel(parent=Dialog)
+ self.label_4.setObjectName("label_4")
+ self.formLayout.setWidget(3, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_4)
+ self.playerList = QtWidgets.QListWidget(parent=Dialog)
+ self.playerList.setObjectName("playerList")
+ self.formLayout.setWidget(3, QtWidgets.QFormLayout.ItemRole.FieldRole, self.playerList)
+ self.verticalLayout.addLayout(self.formLayout)
+ self.buttonBox = QtWidgets.QDialogButtonBox(parent=Dialog)
+ self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal)
+ self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Ok)
+ self.buttonBox.setObjectName("buttonBox")
+ self.verticalLayout.addWidget(self.buttonBox)
+
+ self.retranslateUi(Dialog)
+ self.buttonBox.accepted.connect(Dialog.accept) # type: ignore
+ self.buttonBox.rejected.connect(Dialog.reject) # type: ignore
+ QtCore.QMetaObject.connectSlotsByName(Dialog)
+
+ def retranslateUi(self, Dialog):
+ _translate = QtCore.QCoreApplication.translate
+ Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
+ self.label.setText(_translate("Dialog", "Reader"))
+ self.label_2.setText(_translate("Dialog", "Phonetics"))
+ self.label_3.setText(_translate("Dialog", "Alert Outputs"))
+ self.label_4.setText(_translate("Dialog", "Player Outputs"))
diff --git a/ui/Preferences.ui b/ui/Preferences.ui
new file mode 100644
index 0000000..16f5f11
--- /dev/null
+++ b/ui/Preferences.ui
@@ -0,0 +1,109 @@
+
+
+ Dialog
+
+
+
+ 0
+ 0
+ 601
+ 265
+
+
+
+ Dialog
+
+
+ -
+
+
-
+
+
+ Reader
+
+
+
+ -
+
+
+ -
+
+
+ Phonetics
+
+
+
+ -
+
+
+ -
+
+
+ Alert Outputs
+
+
+
+ -
+
+
+ -
+
+
+ Player Outputs
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ Dialog
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ Dialog
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/ui/display.css b/ui/display.css
index 0227e23..5baf7a0 100644
--- a/ui/display.css
+++ b/ui/display.css
@@ -1,5 +1,5 @@
body {
- font-family: "opendyslexic", sans-serif;
+ font-family: "{readerFont}", sans-serif;
}
hr {
height: 2px;
@@ -18,6 +18,6 @@ p, li {
font-size: 24px;
}
p.phonetic {
- font-family: "Gentium", sans-serif;
+ font-family: "{phoneticFont}", sans-serif;
font-size: 40px;
}
diff --git a/ui/resources.rcc b/ui/resources.rcc
index d584d54..30067ce 100644
Binary files a/ui/resources.rcc and b/ui/resources.rcc differ