Working checkpoint

This commit is contained in:
Christopher T. Johnson
2023-11-10 21:48:15 -05:00
parent e9dbadb5e3
commit 598201425c
16 changed files with 1132 additions and 0 deletions

2
.gitignore vendored
View File

@@ -1,3 +1,5 @@
venv
*~
\#*
__pycache__
*.db

4
Makefile Normal file
View File

@@ -0,0 +1,4 @@
main.py: ui/*.py
%.py:%.ui
pyuic6 $< >$@

5
clean.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash
isort --profile black *.py lib/*.py
black *.py lib/*.py
flynt *.py lib/*.py

2
lib/__init__.py Normal file
View File

@@ -0,0 +1,2 @@
from .books import Book
from .read import EditDialog

67
lib/books.py Normal file
View File

@@ -0,0 +1,67 @@
import json
import os
import xml.dom.minidom
class Book:
sections = []
metadata = {}
def __init__(self, src: str) -> None:
super(Book, self).__init__()
self.parse_book(src)
return
def parse_book(self, src: str) -> None:
with open(f"{src}/content.opf", "r") as f:
dom = xml.dom.minidom.parse(f)
metadata = dom.getElementsByTagName("metadata")[0]
for meta in metadata.childNodes:
if meta.nodeType != xml.dom.Node.ELEMENT_NODE:
continue
if meta.prefix == "dc":
self.metadata[meta.localName] = meta.firstChild.data
#
# The manifest contains a list of all the files contained in this
# EPUB
#
manifest = dom.getElementsByTagName("manifest")[0]
#
# The spine contains the documents in order they are read
#
spine = dom.getElementsByTagName("spine")[0]
for itemref in spine.childNodes:
if itemref.nodeType != xml.dom.Node.ELEMENT_NODE:
continue
# If linear == "no" skip
if (
itemref.hasAttribute("linear")
and itemref.getAttribute("linear") == "no"
):
continue
idref = itemref.getAttribute("idref")
for item in manifest.childNodes:
if item.nodeType != xml.dom.Node.ELEMENT_NODE:
continue
id = item.getAttribute("id")
if id == idref:
break
#
# A properly created *.opf will always have a correct
# spin/manifest.
#
href = item.getAttribute("href")
print(f"{idref}: {href}")
self.parse_section(src, href)
return
def parse_section(self, src: str, href: str) -> None:
with open(f"{src}/{href}") as f:
dom = xml.dom.minidom.parse(f)
title = dom.getElementsByTagName("title")[0].firstChild.data
body = dom.getElementsByTagName("body")[0]
paragraphs = []
for p in body.getElementsByTagName("p"):
paragraphs.append(p.toxml())
self.sections.append({"title": title, "paragraphs": paragraphs})
return

277
lib/read.py Normal file
View File

@@ -0,0 +1,277 @@
import json
from PyDictionary import PyDictionary # type: ignore[import-untyped]
from PyQt6.QtCore import Qt, pyqtSlot
from PyQt6.QtGui import (
QFont,
QTextCharFormat,
QTextCursor,
QTextDocument,
QTextListFormat,
)
from PyQt6.QtSql import QSqlDatabase, QSqlQuery, QSqlQueryModel
from PyQt6.QtWidgets import QDialog
from main import query_error
from ui.EditDialog import Ui_Dialog
class EditDialog(QDialog, Ui_Dialog):
def __init__(self, book_id: int, person_id: int) -> None:
super(EditDialog, self).__init__()
self.book_id = book_id
self.person_id = person_id
self.setupUi(self)
self.current_paragraph(self.person_id)
self.paraEdit.setReadOnly(True)
self.defEdit.setReadOnly(True)
self.stackedWidget.setCurrentIndex(0)
self.defineBtn.clicked.connect(self.defineAction)
self.showBtn.clicked.connect(self.showAction)
self.nextBtn.clicked.connect(self.nextAction)
self.prevBtn.clicked.connect(self.prevAction)
return
def current_paragraph(self, person_id: int) -> None:
query = QSqlQuery()
query.prepare("SELECT * FROM people WHERE person_id = :person_id")
query.bindValue(":person_id", person_id)
query.exec()
query.next()
paragraph_id = query.value("paragraph_id")
self.display_paragraph(paragraph_id)
return
def display_paragraph(self, paragraph_id: int) -> None:
self.paragraph_id = paragraph_id
query = QSqlQuery()
query.prepare("SELECT * FROM paragraphs WHERE paragraph_id = :paragraph_id")
query.bindValue(":paragraph_id", paragraph_id)
query.exec()
query.next()
self.section_id = query.value("section_id")
self.paraSequence = query.value("sequence")
cursor = self.paraEdit.textCursor()
cursor.movePosition(QTextCursor.MoveOperation.Start)
cursor.movePosition(
QTextCursor.MoveOperation.End, QTextCursor.MoveMode.KeepAnchor
)
cursor.removeSelectedText()
cursor.insertHtml(query.value("content"))
query.prepare(
"SELECT * FROM word_paragraph " "WHERE paragraph_id = :paragraph_id"
)
query.bindValue(":paragraph_id", self.paragraph_id)
if not query.exec():
query_error(query)
def_format = QTextCharFormat()
def_format.setFontUnderline(True)
cursor = QTextCursor(self.paraEdit.document())
while query.next():
start = query.value("start")
end = query.value("end")
cursor.setPosition(start, QTextCursor.MoveMode.MoveAnchor)
cursor.setPosition(end, QTextCursor.MoveMode.KeepAnchor)
cursor.setCharFormat(def_format)
cursor.setPosition(0)
self.paraEdit.setTextCursor(cursor)
return
@pyqtSlot()
def defineAction(self) -> None:
cursor = self.paraEdit.textCursor()
word = cursor.selectedText()
start = cursor.selectionStart()
end = cursor.selectionEnd()
if start != end:
word = word.strip()
if len(word) == 0 or word.find(" ") >= 0:
return
if start > end:
tmp = start
start = end
end = tmp
query = QSqlQuery()
query.prepare("SELECT * FROM words WHERE word = :word")
query.bindValue(":word", word)
if not query.exec():
query_error(query)
if query.next(): # we have something
self.defined(query.value("word_id"), start, end)
return
dictionary = PyDictionary()
meaning = json.dumps(dictionary.meaning(word))
por = dictionary.translate(word, "pt")
query.prepare(
"INSERT INTO words (word, definition, translation) "
"VALUES (:word, :definition, :translation)"
)
query.bindValue(":word", word)
query.bindValue(":definition", meaning)
query.bindValue(":translation", por)
if not query.exec():
query_error(query)
self.defined(query.lastInsertId(), start, end)
return
def defined(self, word_id: int, start: int, end: int) -> None:
query = QSqlQuery()
query.prepare(
"SELECT * FROM word_paragraph "
"WHERE word_id = :word_id "
"AND paragraph_id = :paragraph_id "
"AND start = :start "
"AND end = :end"
)
query.bindValue(":word_id", word_id)
query.bindValue(":paragraph_id", self.paragraph_id)
query.bindValue(":start", start)
query.bindValue(":end", end)
if not query.exec():
query_error(query)
if query.next():
return
query.prepare(
"INSERT INTO word_paragraph VALUES "
"( :word_id, :paragraph_id, :start, :end)"
)
query.bindValue(":word_id", word_id)
query.bindValue(":paragraph_id", self.paragraph_id)
query.bindValue(":start", start)
query.bindValue(":end", end)
if not query.exec():
query_error(query)
def_format = QTextCharFormat()
def_format.setFontUnderline(True)
cursor = QTextCursor(self.paraEdit.document())
cursor.setPosition(start, QTextCursor.MoveMode.MoveAnchor)
cursor.setPosition(end, QTextCursor.MoveMode.KeepAnchor)
cursor.setCharFormat(def_format)
return
def display_definition(self) -> None:
cursor = self.paraEdit.textCursor()
query = QSqlQuery()
query.prepare(
"SELECT w.* FROM word_paragraph wp "
"LEFT JOIN words w "
"ON (w.word_id = wp.word_id) "
"WHERE :position BETWEEN wp.start AND wp.end "
"AND wp.paragraph_id = :paragraph_id"
)
query.bindValue(":position", cursor.position())
query.bindValue(":paragraph_id", self.paragraph_id)
print("display_definition()", cursor.position())
if not query.exec():
query_error(query)
if not query.next():
return
word = query.value("word")
definition = json.loads(query.value("definition"))
self.defEdit.document().clear()
cursor = self.defEdit.textCursor()
word_format = QTextCharFormat()
word_format.setFontPointSize(48)
word_format.setFontWeight(QFont.Weight.Bold)
cursor.insertText(word, word_format)
typeFormat = QTextListFormat()
typeFormat.setStyle(QTextListFormat.Style.ListDisc)
typeFormat.setIndent(1)
defFormat = QTextListFormat()
defFormat.setStyle(QTextListFormat.Style.ListCircle)
defFormat.setIndent(2)
word_format.setFontWeight(QFont.Weight.Normal)
word_format.setFontPointSize(16)
cursor.setCharFormat(word_format)
for key in definition.keys():
cursor.insertList(typeFormat)
cursor.insertText(key)
cursor.insertList(defFormat)
first = True
for a_def in definition[key]:
if not first:
cursor.insertBlock()
cursor.insertText(a_def)
first = False
return
@pyqtSlot()
def showAction(self) -> None:
idx = self.stackedWidget.currentIndex()
if idx == 0:
self.display_definition()
self.stackedWidget.setCurrentIndex(1 - idx)
return
def nextDefinition(self):
cursor = self.paraEdit.textCursor()
position = cursor.position()
print(position)
formats = cursor.block().textFormats()
found = None
for f in formats:
wc = QTextCursor(cursor)
wc.setPosition(f.start)
wc.movePosition(
QTextCursor.MoveOperation.Right,
QTextCursor.MoveMode.KeepAnchor,
f.length,
)
word = wc.selectedText()
cf = wc.charFormat()
if f.start <= position:
continue
if not cf.fontUnderline():
continue
if not found:
found = f
elif f.start < found.start:
found = f
if found:
cursor.setPosition(found.start)
self.paraEdit.setTextCursor(cursor)
self.display_definition()
return
@pyqtSlot()
def nextAction(self) -> None:
if self.stackedWidget.currentIndex() == 1:
self.nextDefinition()
return
paraQuery = QSqlQuery()
paraQuery.prepare(
"SELECT * FROM paragraphs WHERE "
"section_id=:section_id AND sequence = :sequence"
)
paraQuery.bindValue(":section_id", self.section_id)
paraQuery.bindValue(":sequence", self.paraSequence + 1)
if not paraQuery.exec():
query_error(paraQuery)
if not paraQuery.next():
secQuery = QSqlQuery()
secQuery.prepare(
"SELECT * FROM sections WHERE book_id=:book_id "
"AND sequence = "
"(SELECT sequence FROM sections WHERE "
"section_id = :section_id)+1"
)
secQuery.bindValue(":book_id", self.book_id)
secQuery.bindValue(":section_id", self.section_id)
if not secQuery.exec():
query_error(secQuery)
if not secQuery.next():
return
self.paraSequence = 0
self.section_id = secQuery.value("section_id")
paraQuery.bindValue(":section_id", self.section_id)
paraQuery.bindValue(":sequence", self.paraSequence)
if not paraQuery.exec():
query_error(paraQuery)
paraQuery.next()
self.display_paragraph(paraQuery.value("paragraph_id"))
return
@pyqtSlot()
def prevAction(self) -> None:
return

286
main.py Executable file
View File

@@ -0,0 +1,286 @@
#!/usr/bin/env python3
import os
import re
import sys
from PyQt6.QtCore import Qt, pyqtSlot
from PyQt6.QtGui import (
QFont,
QTextCharFormat,
QTextCursor,
QTextDocument,
QTextListFormat,
)
from PyQt6.QtSql import QSqlDatabase, QSqlQuery, QSqlQueryModel
from PyQt6.QtWidgets import QApplication, QFileDialog, QMainWindow
from lib import *
from ui.MainWindow import Ui_MainWindow
# from ui.testWindow import Ui_MainWindow
def query_error(query: QSqlQuery) -> None:
print(
"SQL Error:\n{}\n{}\n{}:{}".format(
query.executedQuery(),
query.boundValues(),
query.lastError().type(),
query.lastError().text(),
)
)
raise Exception("SQL Error")
class MainWindow(QMainWindow, Ui_MainWindow):
book_id = 0
def __init__(self) -> None:
super(MainWindow, self).__init__()
self.setupUi(self)
model = QSqlQueryModel()
query = QSqlQuery("SELECT * FROM people ORDER BY name")
model.setQuery(query)
self.peopleView.setModel(model)
self.peopleView.setModelColumn(1)
# self.load_definition(word, PyDictionary.meaning(word))
# self.wordButton.clicked.connect(self.wordAction)
self.ReadButton.clicked.connect(self.readAction)
self.bookBtn.clicked.connect(self.bookAction)
self.show()
return
@pyqtSlot()
def bookAction(self) -> None:
directory = QFileDialog.getExistingDirectory()
book = Book(directory)
self.book_id = self.store_book(book)
return
def store_book(self, book: Book) -> int:
uuid = book.metadata["identifier"]
query = QSqlQuery()
query.prepare(
"SELECT COUNT(*) AS number, book_id FROM books b " "WHERE b.uuid = :uuid"
)
query.bindValue(":uuid", uuid)
if not query.exec():
query_error(query)
query.next()
if query.value("number") > 0:
book_id: int = query.value("book_id")
return book_id
query.prepare(
"INSERT INTO books (title, author, uuid, level) VALUES ("
":title, :author, :uuid, 0)"
)
query.bindValue(":title", book.metadata["title"])
query.bindValue(":author", book.metadata["creator"])
query.bindValue(":uuid", uuid)
if not query.exec():
query_error(query)
book_id = query.lastInsertId()
section_query = QSqlQuery()
section_query.prepare(
"INSERT INTO sections (title, sequence, book_id) "
"VALUES (:title, :sequence, :book_id)"
)
section_query.bindValue(":book_id", book_id)
para_query = QSqlQuery()
para_query.prepare(
"INSERT INTO paragraphs (section_id, sequence, content) "
"VALUES (:section_id, :sequence, :content)"
)
for seq, section in enumerate(book.sections):
section_query.bindValue(":title", section["title"])
section_query.bindValue(":sequence", seq)
if not section_query.exec():
query_error(section_query)
section_id = query.lastInsertId()
para_query.bindValue(":section_id", section_id)
for ps, paragraph in enumerate(section["paragraphs"]):
para_query.bindValue(":sequence", ps)
para_query.bindValue(":content", paragraph)
if not para_query.exec():
query_error(para_query)
return book_id
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
return
@pyqtSlot()
def readAction(self) -> None:
indexes = self.peopleView.selectedIndexes()
if len(indexes) < 1:
return
person_id = indexes[0].siblingAtColumn(0).data()
name = indexes[0].data()
print(person_id, name)
dlg = EditDialog(self.book_id, person_id)
dlg.exec()
return
SQL_CMDS = [
"PRAGMA foreign_keys=ON",
"CREATE TABLE IF NOT EXISTS words "
"(word_id INTEGER PRIMARY KEY AUTOINCREMENT, word TEXT, definition TEXT, "
"translation TEXT)",
"CREATE TABLE IF NOT EXISTS books "
"(book_id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, author TEXT, "
"uuid TEXT, level INTEGER)",
"CREATE TABLE IF NOT EXISTS sections "
"(section_id INTEGER PRIMARY KEY AUTOINCREMENT, "
"title TEXT, sequence INTEGER, "
"book_id INTEGER REFERENCES books ON DELETE CASCADE) ",
"CREATE TABLE IF NOT EXISTS paragraphs "
"(paragraph_id INTEGER PRIMARY KEY AUTOINCREMENT, "
"section_id INTEGER REFERENCES sections ON DELETE CASCADE, "
"sequence INTEGER NOT NULL DEFAULT 0, "
"content TEXT)",
"CREATE TABLE IF NOT EXISTS people "
"(person_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, "
"organization TEXT, "
"paragraph_id INTEGER REFERENCES paragraphs ON DELETE CASCADE)",
"CREATE TABLE IF NOT EXISTS person_book "
"(person_id INTEGER REFERENCES people ON DELETE CASCADE, "
"book_id INTEGER REFERENCES books ON DELETE CASCADE)",
"CREATE TABLE IF NOT EXISTS word_paragraph "
"(word_id INTEGER REFERENCES words ON DELETE CASCADE, "
"paragraph_id INTEGER REFERENCES paragraphs ON DELETE CASCADE, "
"start INTEGER NOT NULL, end INTEGER NOT NULL)",
]
def schema_update(db: QSqlDatabase) -> None:
query = QSqlQuery()
for sql in SQL_CMDS:
print(sql)
inlower = sql.lower()
if not inlower.startswith("create table "):
if not query.exec(sql):
query_error(query)
continue
create_cmd = re.sub(r"IF NOT EXISTS ", "", sql)
create_cmd = re.sub(r"\s\s*", " ", create_cmd)
matches = re.search(r"^(CREATE TABLE )([^ ]+)( \(.+)$", create_cmd)
if matches:
table_name = matches.group(2)
create_cmd = (
matches.group(1) + '"' + matches.group(2) + '"' + matches.group(3)
)
else:
raise AttributeError(f"No match found: {create_cmd}")
query.prepare("SELECT sql FROM sqlite_schema WHERE tbl_name = :tbl")
query.bindValue(":tbl", table_name)
if not query.exec():
query_error(query)
query.next()
old = query.value(0)
if not old:
if not query.exec(sql):
query_error(query)
continue
if old.lower() == create_cmd.lower():
continue
print(old.lower())
print(create_cmd.lower())
print(f"Updating: {table_name}")
# Step 1 turn off foreign key constraints
if not query.exec("PRAGMA foreign_keys=OFF"):
query_error(query)
# Step 2 start a transaction
db.transaction()
# Step 3 remember old indexes, triggers, and views
# Step 4 create new table
new_table_name = table_name + "_new"
if not query.exec(matches.group(1) + new_table_name + matches.group(3)):
query_error(query)
# step 5 transfer content
coldefs = re.search(r"\((.+)\)", old).group(1).split(", ")
cols = [x.split(" ")[0] for x in coldefs]
if not query.exec(
"INSERT INTO "
+ new_table_name
+ "("
+ ", ".join(cols)
+ ") SELECT "
+ ", ".join(cols)
+ " FROM "
+ table_name
):
query_error(query)
# step 6 Drop old table
if not query.exec("DROP TABLE " + table_name):
query_error(query)
# step 6 rename new table to old table
if not query.exec("ALTER TABLE " + new_table_name + " RENAME TO " + table_name):
query_error(query)
# step 8 create indexes, triggers, and views
# step 9 rebuild affected views
# step 10 turn foreign key constrants back on
if not query.exec("PRAGMA foreign_keys=ON"):
query_error(query)
# step 11 commit the changes
db.commit()
return
def main() -> int:
db = QSqlDatabase()
db = db.addDatabase("QSQLITE")
db.setDatabaseName("twel.db")
db.open()
app = QApplication(sys.argv)
schema_update(db)
window: QMainWindow = MainWindow()
return app.exec()
if __name__ == "__main__":
outOfDate = []
for fileName in os.listdir("ui"):
if not fileName.endswith(".py"):
continue
uiName = fileName[:-3] + ".ui"
if os.path.getmtime("ui/" + uiName) > os.path.getmtime("ui/" + fileName):
outOfDate.append(fileName)
if len(outOfDate) > 0:
print(f"UI out of date: {', '.join(outOfDate)}")
sys.exit(1)
sys.exit(main())

8
mypy.ini Normal file
View File

@@ -0,0 +1,8 @@
[mypy]
warn_redundant_casts = True
disallow_untyped_defs = True
warn_return_any = True
warn_unused_configs = True
[mypy-ui.*]
disallow_untyped_defs = False

78
ui/EditDialog.py Normal file
View File

@@ -0,0 +1,78 @@
# Form implementation generated from reading ui file 'ui/EditDialog.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(761, 427)
self.horizontalLayout = QtWidgets.QHBoxLayout(Dialog)
self.horizontalLayout.setObjectName("horizontalLayout")
self.stackedWidget = QtWidgets.QStackedWidget(parent=Dialog)
self.stackedWidget.setObjectName("stackedWidget")
self.page = QtWidgets.QWidget()
self.page.setObjectName("page")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.page)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.paraEdit = QtWidgets.QTextEdit(parent=self.page)
font = QtGui.QFont()
font.setFamily("OpenDyslexic")
font.setPointSize(16)
self.paraEdit.setFont(font)
self.paraEdit.setObjectName("paraEdit")
self.verticalLayout_2.addWidget(self.paraEdit)
self.stackedWidget.addWidget(self.page)
self.page_2 = QtWidgets.QWidget()
self.page_2.setObjectName("page_2")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.page_2)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.defEdit = QtWidgets.QTextEdit(parent=self.page_2)
font = QtGui.QFont()
font.setFamily("OpenDyslexic")
self.defEdit.setFont(font)
self.defEdit.setObjectName("defEdit")
self.verticalLayout_3.addWidget(self.defEdit)
self.stackedWidget.addWidget(self.page_2)
self.horizontalLayout.addWidget(self.stackedWidget)
self.widget = QtWidgets.QWidget(parent=Dialog)
self.widget.setObjectName("widget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.widget)
self.verticalLayout.setObjectName("verticalLayout")
self.defineBtn = QtWidgets.QPushButton(parent=self.widget)
self.defineBtn.setObjectName("defineBtn")
self.verticalLayout.addWidget(self.defineBtn)
self.wordsBtn = QtWidgets.QPushButton(parent=self.widget)
self.wordsBtn.setObjectName("wordsBtn")
self.verticalLayout.addWidget(self.wordsBtn)
self.showBtn = QtWidgets.QPushButton(parent=self.widget)
self.showBtn.setObjectName("showBtn")
self.verticalLayout.addWidget(self.showBtn)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding)
self.verticalLayout.addItem(spacerItem)
self.nextBtn = QtWidgets.QPushButton(parent=self.widget)
self.nextBtn.setObjectName("nextBtn")
self.verticalLayout.addWidget(self.nextBtn)
self.prevBtn = QtWidgets.QPushButton(parent=self.widget)
self.prevBtn.setObjectName("prevBtn")
self.verticalLayout.addWidget(self.prevBtn)
self.horizontalLayout.addWidget(self.widget)
self.retranslateUi(Dialog)
self.stackedWidget.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.defineBtn.setText(_translate("Dialog", "Define"))
self.wordsBtn.setText(_translate("Dialog", "Words"))
self.showBtn.setText(_translate("Dialog", "Show"))
self.nextBtn.setText(_translate("Dialog", "Next"))
self.prevBtn.setText(_translate("Dialog", "Previous"))

109
ui/EditDialog.ui Normal file
View File

@@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>761</width>
<height>427</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="page">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTextEdit" name="paraEdit">
<property name="font">
<font>
<family>OpenDyslexic</family>
<pointsize>16</pointsize>
</font>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_2">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QTextEdit" name="defEdit">
<property name="font">
<font>
<family>OpenDyslexic</family>
</font>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="defineBtn">
<property name="text">
<string>Define</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="wordsBtn">
<property name="text">
<string>Words</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="showBtn">
<property name="text">
<string>Show</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="nextBtn">
<property name="text">
<string>Next</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="prevBtn">
<property name="text">
<string>Previous</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

56
ui/MainWindow.py Normal file
View File

@@ -0,0 +1,56 @@
# Form implementation generated from reading ui file 'ui/MainWindow.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_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(parent=MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
self.horizontalLayout.setObjectName("horizontalLayout")
self.peopleView = QtWidgets.QListView(parent=self.centralwidget)
self.peopleView.setObjectName("peopleView")
self.horizontalLayout.addWidget(self.peopleView)
self.widget = QtWidgets.QWidget(parent=self.centralwidget)
self.widget.setObjectName("widget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.widget)
self.verticalLayout.setObjectName("verticalLayout")
self.WordButton = QtWidgets.QPushButton(parent=self.widget)
self.WordButton.setObjectName("WordButton")
self.verticalLayout.addWidget(self.WordButton)
self.ReadButton = QtWidgets.QPushButton(parent=self.widget)
self.ReadButton.setObjectName("ReadButton")
self.verticalLayout.addWidget(self.ReadButton)
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.horizontalLayout.addWidget(self.widget)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(parent=MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 22))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(parent=MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.WordButton.setText(_translate("MainWindow", "Words"))
self.ReadButton.setText(_translate("MainWindow", "Read"))
self.bookBtn.setText(_translate("MainWindow", "Add Book"))

77
ui/MainWindow.ui Normal file
View File

@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QListView" name="peopleView"/>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="WordButton">
<property name="text">
<string>Words</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ReadButton">
<property name="text">
<string>Read</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="bookBtn">
<property name="text">
<string>Add Book</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>

42
ui/WordDialog.py Normal file
View File

@@ -0,0 +1,42 @@
# Form implementation generated from reading ui file 'ui/WordDialog.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(802, 300)
self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.wordList = QtWidgets.QListView(parent=Dialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.wordList.sizePolicy().hasHeightForWidth())
self.wordList.setSizePolicy(sizePolicy)
self.wordList.setObjectName("wordList")
self.horizontalLayout.addWidget(self.wordList)
self.definition = QtWidgets.QTextEdit(parent=Dialog)
self.definition.setObjectName("definition")
self.horizontalLayout.addWidget(self.definition)
self.verticalLayout.addLayout(self.horizontalLayout)
self.buttonBox = QtWidgets.QDialogButtonBox(parent=Dialog)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Ok)
self.buttonBox.setObjectName("buttonBox")
self.verticalLayout.addWidget(self.buttonBox)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))

45
ui/WordDialog.ui Normal file
View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>802</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QListView" name="wordList">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="definition"/>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

37
ui/testWindow.py Normal file
View File

@@ -0,0 +1,37 @@
# Form implementation generated from reading ui file 'ui/testWindow.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_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(parent=MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.textEdit = QtWidgets.QTextEdit(parent=self.centralwidget)
self.textEdit.setObjectName("textEdit")
self.verticalLayout.addWidget(self.textEdit)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(parent=MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 19))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(parent=MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))

37
ui/testWindow.ui Normal file
View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTextEdit" name="textEdit"/>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>19</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>