diff --git a/lib/read.py b/lib/read.py
index 9b2b4c0..83dec45 100644
--- a/lib/read.py
+++ b/lib/read.py
@@ -12,6 +12,7 @@ from PyQt6.QtCore import (
QResource,
Qt,
QTimer,
+ pyqtSignal,
pyqtSlot,
)
from PyQt6.QtGui import (
@@ -39,8 +40,10 @@ from ui.EditDialog import Ui_Dialog
class EditDialog(QDialog, Ui_Dialog):
block: int
paragraphs = True
+ displayedWord = pyqtSignal(int)
- def __init__(self, person_id: int) -> None:
+ def __init__(self, session, person_id: int) -> None:
+ self.session = session
super(EditDialog, self).__init__()
self.person_id = person_id
if not QResource.registerResource(
@@ -65,12 +68,20 @@ class EditDialog(QDialog, Ui_Dialog):
self.block = blockNumber
self.savePosition()
self.stackedWidget.setCurrentIndex(0)
+ #
+ # Connect widgets
+ #
self.defineBtn.clicked.connect(self.defineAction)
self.printBtn.clicked.connect(self.printAction)
self.scrollBtn.clicked.connect(self.scrollAction)
self.nextBtn.clicked.connect(self.nextAction)
self.prevBtn.clicked.connect(self.prevAction)
+ self.sessionBtn.clicked.connect(self.session.timerAction)
self.paraEdit.verticalScrollBar().valueChanged.connect(self.scrollSlot)
+ #
+ # Connect signals
+ #
+ self.displayedWord.connect(self.session.addWord)
return
#
@@ -148,7 +159,6 @@ class EditDialog(QDialog, Ui_Dialog):
if msPerTick < 3:
msPerTick = 3
self.target = value + delta
- print(f"delta: {delta}, pixels: {self.pxPerTick}, ms: {msPerTick}")
timer = QTimer(self)
timer.timeout.connect(self.softTick)
timer.start(msPerTick)
@@ -200,7 +210,6 @@ class EditDialog(QDialog, Ui_Dialog):
@pyqtSlot()
def defineAction(self) -> None:
- print("defineAction")
if self.paragraphs:
self.showDefinition()
else:
@@ -512,6 +521,7 @@ class EditDialog(QDialog, Ui_Dialog):
cursor.insertHtml(self.defToHtml(word, definition))
cursor.setPosition(0)
self.defEdit.setTextCursor(cursor)
+ self.displayedWord.emit(query.value("word_id"))
return
def showDefinition(self) -> None:
diff --git a/main.py b/main.py
index b7b6dce..0980923 100755
--- a/main.py
+++ b/main.py
@@ -1,10 +1,33 @@
#!/usr/bin/env python3
+#
+# TODO:
+# Start/Stop Session
+# Record all words examined
+# Record all words defined after start session
+# Record paragraph start and stop
+#
+# Add definition to definition
+# Follow definition links
+# Print subset of words, limit to words from this session's paragraphs
+# plus defined during session
+# Add Note per session
+# Add book import dialog
+# Add person create/edit dialog
+# Reading scroll with speed control
+# Move controls out of reading window.
+# Ability to edit text with updates to word-section links
+# Need to be able to place a visible cursor in text.
+# Scroll to cursor
+# XXX:
+# Scrolling is messed up. Need a way of marking current line.
+#
import os
import re
import sys
+from datetime import datetime, timedelta
from typing import cast
-from PyQt6.QtCore import QModelIndex, Qt, pyqtSlot
+from PyQt6.QtCore import QModelIndex, Qt, QTimer, pyqtSignal, pyqtSlot
from PyQt6.QtGui import (
QAction,
QFont,
@@ -37,181 +60,97 @@ def query_error(query: QSqlQuery) -> None:
)
raise Exception("SQL Error")
-
-class ModelOverride(QSqlQueryModel):
- enableFlag = False
-
- def flags(self, index: QModelIndex) -> Qt.ItemFlag:
- itemFlags = super(ModelOverride, self).flags(index)
- if self.enableFlag:
- return itemFlags
- value = index.siblingAtColumn(3).data()
- if not value or value < 1:
- itemFlags &= ~(
- Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled
- )
- return itemFlags
-
- @pyqtSlot()
- def toggle(self) -> None:
- self.enableFlag = not self.enableFlag
- sender = cast(QPushButton, self.sender())
- if self.enableFlag:
- sender.setText("Disable")
- else:
- sender.setText("Enable")
- return
-
-
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self) -> None:
super(MainWindow, self).__init__()
self.setupUi(self)
- model = ModelOverride()
+ #model = ModelOverride()
+ model = QSqlQueryModel()
query = QSqlQuery("SELECT * FROM people ORDER BY name")
model.setQuery(query)
self.peopleView.setModel(model)
self.peopleView.setModelColumn(1)
- self.toggleBtn.clicked.connect(model.toggle)
- self.bookBtn.clicked.connect(self.bookAction)
- self.peopleView.doubleClicked.connect(self.readAction)
- self.actionQuit.triggered.connect(self.close)
- self.createActions()
+ self.actionEditPerson.setEnabled(False)
+ #
+ # Connections
+ #
+ # 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.actionRead.enabledChanged.connect(self.readBtn.setEnabled)
+ self.actionAddPerson.triggered.connect(self.addPerson) # Y
+ self.actionEditPerson.triggered.connect(self.editPerson) # Y
+ self.actionEditPerson.enabledChanged.connect(self.editBtn.setEnabled) # Y
+ self.peopleView.doubleClicked.connect(self.editPerson) # Y
+ self.peopleView.clicked.connect(self.selectedPerson) # Y
self.show()
return
- def createActions(self) -> None:
- query = QSqlQuery()
- query.prepare("SELECT * FROM books ORDER BY title")
- if not query.exec():
- query_error(query)
- while query.next():
- action = QAction(query.value("title"), self)
- action.setData(query.value("book_id"))
- action.triggered.connect(self.setBookAction)
- self.menuBooks.addAction(action)
+ @pyqtSlot(QModelIndex)
+ def selectedPerson(self, index: QModelIndex) -> None:
+ person_id = index.siblingAtColumn(0).data()
+ self.actionEditPerson.setEnabled(True)
+ book_id = index.siblingAtColumn(3).data()
+ if not book_id or book_id < 0:
+ self.actionRead.setEnabled(False)
+ else:
+ self.actionRead.setEnabled(True)
return
+
+ @pyqtSlot(bool)
+ def enablePerson(self, flag: bool) -> None:
+ if flag:
+ self.editBtn.setEnabled(False)
+ self.readBtn.setEnabled(False)
+ else:
+ self.editBtn.setEnabled(True)
+ self.readBtn.setEnabled(True)
+ return
+
@pyqtSlot()
- def setBookAction(self) -> None:
- action = cast(QAction, self.sender())
- book_id = action.data()
- indexes = self.peopleView.selectedIndexes()
- if len(indexes) < 1:
- return
- person_id = indexes[0].siblingAtColumn(0).data()
- query = QSqlQuery()
- query.prepare(
- "SELECT * FROM person_book "
- "WHERE person_id = :person_id "
- "AND book_id = :book_id"
- )
- query.bindValue(":person_id", person_id)
- query.bindValue(":book_id", book_id)
- if not query.exec():
- query_error(query)
- if not query.next():
- query.prepare(
- "SELECT * FROM sections WHERE sequence = 0 "
- "AND book_id = :book_id"
- )
- query.bindValue(":book_id", book_id)
- if not query.exec():
- query_error(query)
- if not query.next():
- raise Exception(f"book_id: {book_id} has no section 0!")
- section_id = query.value("section_id")
- query.prepare(
- "INSERT INTO person_book "
- "VALUES (:person_id, :book_id, :section_id, 0)"
- )
- query.bindValue(":person_id", person_id)
- query.bindValue(":book_id", book_id)
- query.bindValue(":section_id", section_id)
- if not query.exec():
- query_error(query)
- query.prepare(
- "UPDATE people SET book_id = :book_id "
- "WHERE person_id = :person_id"
- )
- query.bindValue(":book_id", book_id)
- query.bindValue(":person_id", person_id)
- if not query.exec():
- query_error(query)
- query.prepare(
- "SELECT p.name,b.title FROM people p "
- "LEFT JOIN books b "
- "ON (p.book_id = b.book_id) "
- "WHERE p.person_id = :person_id"
- )
- query.bindValue(":person_id", person_id)
- if not query.exec():
- query_error(query)
- query.next()
- title = query.value("title")
- name = query.value("name")
- QMessageBox.information(
- self, "Book Assignment", f"{title} was assigned to {name}"
- )
- self.resetPeopleModel()
- return
-
- def resetPeopleModel(self) -> None:
- query = QSqlQuery("SELECT * FROM people ORDER BY name")
- self.peopleView.model().setQuery(query)
- return
-
- @pyqtSlot()
- def bookAction(self) -> None:
- directory = QFileDialog.getExistingDirectory()
- self.book = Book(directory)
- return
-
- def load_definition(self, word: str, definition: dict) -> None:
- document = None # self.textEdit.document()
- myCursor = QTextCursor(document)
- myCursor.movePosition(QTextCursor.MoveOperation.Start)
- myCursor.movePosition(
- QTextCursor.MoveOperation.End, QTextCursor.MoveMode.KeepAnchor
- )
- myCursor.removeSelectedText()
- word_format = QTextCharFormat()
- # word_format.setFontFamily("Caveat")
- word_format.setFontPointSize(48)
- word_format.setFontWeight(QFont.Weight.Bold)
- myCursor.insertText(word, word_format)
- # word_format.setFont(document.defaultFont())
- typeFormat = QTextListFormat()
- typeFormat.setStyle(QTextListFormat.Style.ListDisc)
- typeFormat.setIndent(1)
- defFormat = QTextListFormat()
- defFormat.setStyle(QTextListFormat.Style.ListCircle)
- defFormat.setIndent(2)
- myCursor.setCharFormat(word_format)
- for key in definition.keys():
- myCursor.insertList(typeFormat)
- myCursor.insertText(key)
- myCursor.insertList(defFormat)
- first = True
- for a_def in definition[key]:
- if not first:
- myCursor.insertBlock()
- myCursor.insertText(a_def)
- first = False
+ def addPerson(self) -> None:
+ dlg = PersonDialog()
+ dlg.exec()
return
@pyqtSlot()
@pyqtSlot(QModelIndex)
- def readAction(self, index: QModelIndex | None = None) -> None:
- if index:
- person_id = index.siblingAtColumn(0).data()
- else:
- indexes = self.peopleView.selectedIndexes()
- if len(indexes) < 1:
- return
- person_id = indexes[0].siblingAtColumn(0).data()
- dlg = EditDialog(person_id)
- dlg.exec()
+ def editPerson(self, index = None ) -> None:
+ print("Edit a person")
+ return
+
+ @pyqtSlot()
+ def addBook(self) -> None:
+ directory = QFileDialog.getExistingDirectory()
+ self.book = Book(directory)
+ return
+
+ @pyqtSlot()
+ def editBook(self) -> None:
+ print("Edit Book")
+ return
+ session = None
+ setPerson = pyqtSignal(int)
+
+ @pyqtSlot()
+ def readBook(self) -> None:
+ indexes = self.peopleView.selectedIndexes()
+ if len(indexes) < 1:
+ return
+ person_id = indexes[0].siblingAtColumn(0).data()
+ if not self.session:
+ self.session = SessionDialog()
+ self.setPerson.connect(self.session.setPerson)
+ self.session.show()
+ self.session.raise_()
+ self.setPerson.emit(person_id)
+ self.dlg = EditDialog(self.session, person_id)
+ self.dlg.show()
+ self.dlg.raise_()
return
diff --git a/ui/EditDialog.py b/ui/EditDialog.py
index 729de8c..d412b2d 100644
--- a/ui/EditDialog.py
+++ b/ui/EditDialog.py
@@ -62,6 +62,14 @@ class Ui_Dialog(object):
self.prevBtn = QtWidgets.QPushButton(parent=self.widget)
self.prevBtn.setObjectName("prevBtn")
self.verticalLayout.addWidget(self.prevBtn)
+ self.line = QtWidgets.QFrame(parent=self.widget)
+ self.line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
+ self.line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
+ self.line.setObjectName("line")
+ self.verticalLayout.addWidget(self.line)
+ self.sessionBtn = QtWidgets.QPushButton(parent=self.widget)
+ self.sessionBtn.setObjectName("sessionBtn")
+ self.verticalLayout.addWidget(self.sessionBtn)
self.horizontalLayout.addWidget(self.widget)
self.retranslateUi(Dialog)
@@ -76,3 +84,4 @@ class Ui_Dialog(object):
self.scrollBtn.setText(_translate("Dialog", "Scroll"))
self.nextBtn.setText(_translate("Dialog", "Next Para"))
self.prevBtn.setText(_translate("Dialog", "Prev Para"))
+ self.sessionBtn.setText(_translate("Dialog", "Start"))
diff --git a/ui/EditDialog.ui b/ui/EditDialog.ui
index 360d78d..dcadad8 100644
--- a/ui/EditDialog.ui
+++ b/ui/EditDialog.ui
@@ -99,6 +99,20 @@
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Start
+
+
+
diff --git a/ui/MainWindow.py b/ui/MainWindow.py
index a4c53bf..c910b0b 100644
--- a/ui/MainWindow.py
+++ b/ui/MainWindow.py
@@ -24,18 +24,25 @@ class Ui_MainWindow(object):
self.widget.setObjectName("widget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.widget)
self.verticalLayout.setObjectName("verticalLayout")
- self.WordButton = QtWidgets.QPushButton(parent=self.widget)
- self.WordButton.setEnabled(False)
- self.WordButton.setObjectName("WordButton")
- self.verticalLayout.addWidget(self.WordButton)
- self.toggleBtn = QtWidgets.QPushButton(parent=self.widget)
- self.toggleBtn.setObjectName("toggleBtn")
- self.verticalLayout.addWidget(self.toggleBtn)
+ self.readBtn = QtWidgets.QPushButton(parent=self.widget)
+ self.readBtn.setObjectName("readBtn")
+ self.verticalLayout.addWidget(self.readBtn)
+ self.editBtn = QtWidgets.QPushButton(parent=self.widget)
+ self.editBtn.setObjectName("editBtn")
+ self.verticalLayout.addWidget(self.editBtn)
+ self.line = QtWidgets.QFrame(parent=self.widget)
+ self.line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
+ self.line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
+ self.line.setObjectName("line")
+ self.verticalLayout.addWidget(self.line)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding)
self.verticalLayout.addItem(spacerItem)
self.bookBtn = QtWidgets.QPushButton(parent=self.widget)
self.bookBtn.setObjectName("bookBtn")
self.verticalLayout.addWidget(self.bookBtn)
+ self.addBtn = QtWidgets.QPushButton(parent=self.widget)
+ self.addBtn.setObjectName("addBtn")
+ self.verticalLayout.addWidget(self.addBtn)
self.horizontalLayout.addWidget(self.widget)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(parent=MainWindow)
@@ -45,25 +52,62 @@ class Ui_MainWindow(object):
self.menuFile.setObjectName("menuFile")
self.menuBooks = QtWidgets.QMenu(parent=self.menubar)
self.menuBooks.setObjectName("menuBooks")
+ self.menuBooks_2 = QtWidgets.QMenu(parent=self.menuBooks)
+ self.menuBooks_2.setObjectName("menuBooks_2")
+ self.menuPeople = QtWidgets.QMenu(parent=self.menuBooks)
+ self.menuPeople.setObjectName("menuPeople")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(parent=MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.actionQuit = QtGui.QAction(parent=MainWindow)
self.actionQuit.setObjectName("actionQuit")
+ self.actionAddBook = QtGui.QAction(parent=MainWindow)
+ self.actionAddBook.setObjectName("actionAddBook")
+ self.actionEditBook = QtGui.QAction(parent=MainWindow)
+ self.actionEditBook.setObjectName("actionEditBook")
+ self.actionAddPerson = QtGui.QAction(parent=MainWindow)
+ self.actionAddPerson.setObjectName("actionAddPerson")
+ self.actionEditPerson = QtGui.QAction(parent=MainWindow)
+ self.actionEditPerson.setObjectName("actionEditPerson")
+ self.actionRead = QtGui.QAction(parent=MainWindow)
+ self.actionRead.setObjectName("actionRead")
self.menuFile.addAction(self.actionQuit)
+ self.menuBooks_2.addAction(self.actionAddBook)
+ self.menuBooks_2.addAction(self.actionEditBook)
+ self.menuPeople.addAction(self.actionAddPerson)
+ self.menuPeople.addAction(self.actionEditPerson)
+ self.menuBooks.addAction(self.menuBooks_2.menuAction())
+ self.menuBooks.addAction(self.menuPeople.menuAction())
self.menubar.addAction(self.menuFile.menuAction())
self.menubar.addAction(self.menuBooks.menuAction())
self.retranslateUi(MainWindow)
+ self.editBtn.clicked.connect(self.actionEditPerson.trigger) # type: ignore
+ self.addBtn.clicked.connect(self.actionAddPerson.trigger) # type: ignore
+ self.bookBtn.clicked.connect(self.actionAddBook.trigger) # type: ignore
+ self.readBtn.clicked.connect(self.actionRead.trigger) # type: ignore
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Reading Helper"))
- self.WordButton.setText(_translate("MainWindow", "Words"))
- self.toggleBtn.setText(_translate("MainWindow", "Enable"))
+ self.readBtn.setText(_translate("MainWindow", "Read"))
+ self.editBtn.setText(_translate("MainWindow", "Edit"))
self.bookBtn.setText(_translate("MainWindow", "Add Book"))
+ self.addBtn.setText(_translate("MainWindow", "Add Person"))
self.menuFile.setTitle(_translate("MainWindow", "File"))
- self.menuBooks.setTitle(_translate("MainWindow", "Books"))
+ self.menuBooks.setTitle(_translate("MainWindow", "Edit"))
+ self.menuBooks_2.setTitle(_translate("MainWindow", "Books"))
+ self.menuPeople.setTitle(_translate("MainWindow", "People"))
self.actionQuit.setText(_translate("MainWindow", "Quit"))
+ self.actionAddBook.setText(_translate("MainWindow", "Add"))
+ self.actionAddBook.setToolTip(_translate("MainWindow", "Add Book"))
+ self.actionEditBook.setText(_translate("MainWindow", "Edit"))
+ self.actionEditBook.setToolTip(_translate("MainWindow", "Edit Book"))
+ self.actionAddPerson.setText(_translate("MainWindow", "Add"))
+ self.actionAddPerson.setToolTip(_translate("MainWindow", "Add A Person"))
+ self.actionEditPerson.setText(_translate("MainWindow", "Edit"))
+ self.actionEditPerson.setToolTip(_translate("MainWindow", "Edit A Person"))
+ self.actionRead.setText(_translate("MainWindow", "Read"))
+ self.actionRead.setToolTip(_translate("MainWindow", "Read Book"))
diff --git a/ui/MainWindow.ui b/ui/MainWindow.ui
index a099c0d..af4e159 100644
--- a/ui/MainWindow.ui
+++ b/ui/MainWindow.ui
@@ -22,19 +22,23 @@
-
-
-
- false
-
+
- Words
+ Read
-
-
+
- Enable
+ Edit
+
+
+
+ -
+
+
+ Qt::Horizontal
@@ -58,6 +62,13 @@
+ -
+
+
+ Add Person
+
+
+
@@ -80,8 +91,24 @@
@@ -92,7 +119,112 @@
Quit
+
+
+ Add
+
+
+ Add Book
+
+
+
+
+ Edit
+
+
+ Edit Book
+
+
+
+
+ Add
+
+
+ Add A Person
+
+
+
+
+ Edit
+
+
+ Edit A Person
+
+
+
+
+ Read
+
+
+ Read Book
+
+
-
+
+
+ editBtn
+ clicked()
+ actionEditPerson
+ trigger()
+
+
+ 722
+ 117
+
+
+ -1
+ -1
+
+
+
+
+ addBtn
+ clicked()
+ actionAddPerson
+ trigger()
+
+
+ 722
+ 532
+
+
+ -1
+ -1
+
+
+
+
+ bookBtn
+ clicked()
+ actionAddBook
+ trigger()
+
+
+ 722
+ 491
+
+
+ -1
+ -1
+
+
+
+
+ readBtn
+ clicked()
+ actionRead
+ trigger()
+
+
+ 722
+ 67
+
+
+ -1
+ -1
+
+
+
+
diff --git a/ui/display.css b/ui/display.css
index 4327686..0227e23 100644
--- a/ui/display.css
+++ b/ui/display.css
@@ -18,6 +18,6 @@ p, li {
font-size: 24px;
}
p.phonetic {
- font-family: "Tex Gyre Heros", sans-serif;
- font-size: 32px;
+ font-family: "Gentium", sans-serif;
+ font-size: 40px;
}
diff --git a/ui/resources.rcc b/ui/resources.rcc
index 4999042..c72d976 100644
Binary files a/ui/resources.rcc and b/ui/resources.rcc differ