From 55dbac5102b9f4325ad37bc235d5558ff419b773 Mon Sep 17 00:00:00 2001 From: "Christopher T. Johnson" Date: Mon, 1 Apr 2024 10:12:12 -0400 Subject: [PATCH] Linter reformat --- esl_reader.py | 3 +- lib/words.py | 537 +++++++++++++++++++++++++++++--------------------- 2 files changed, 319 insertions(+), 221 deletions(-) diff --git a/esl_reader.py b/esl_reader.py index c6d5e81..5a72b91 100755 --- a/esl_reader.py +++ b/esl_reader.py @@ -168,7 +168,8 @@ SQL_CMDS = [ "PRAGMA foreign_keys=ON", # "CREATE TABLE IF NOT EXISTS words " - "(word_id INTEGER PRIMARY KEY AUTOINCREMENT, word TEXT, definition TEXT)", + "(word_id INTEGER PRIMARY KEY AUTOINCREMENT, word TEXT, " + "source TEXT, definition TEXT)", # "CREATE TABLE IF NOT EXISTS books " "(book_id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, author TEXT, " diff --git a/lib/words.py b/lib/words.py index dae3d6b..7361253 100644 --- a/lib/words.py +++ b/lib/words.py @@ -3,8 +3,19 @@ import json import re from typing import Any, Optional, cast -import requests -from PyQt6.QtCore import QMargins, QPoint, QRect, QSize, QUrl, Qt, pyqtSignal +from PyQt6.QtCore import ( + QByteArray, + QEventLoop, + QMargins, + QPoint, + QRect, + QSize, + Qt, + QThread, + QUrl, + pyqtSignal, + pyqtSlot, +) from PyQt6.QtGui import ( QBrush, QColor, @@ -28,27 +39,28 @@ from PyQt6.QtWidgets import QScrollArea, QWidget from lib import query_error + class Fragment: """A fragment of text to be displayed""" - def __init__(self, - text:str, - font:QFont, - audio:str = '', - color: Optional[QColor] = None, - asis: bool = False, - ) -> None: + def __init__( + self, + text: str, + font: QFont, + audio: str = "", + color: Optional[QColor] = None, + asis: bool = False, + ) -> None: self._text = text self._font = font - self._audio:QUrl = QUrl(audio) + self._audio: QUrl = QUrl(audio) self._align = QTextOption( - Qt.AlignmentFlag.AlignLeft - | Qt.AlignmentFlag.AlignBaseline + Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignBaseline ) self._padding = QMargins() self._border = QMargins() self._margin = QMargins() - self._wref = '' + self._wref = "" self._position = QPoint() self._rect = QRect() self._borderRect = QRect() @@ -64,9 +76,13 @@ class Fragment: def __str__(self) -> str: return self.__repr__() - def size(self, width:int) -> QSize: - rect = QRect(self._position,QSize(width,2000)) - flags = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignBaseline | Qt.TextFlag.TextWordWrap + def size(self, width: int) -> QSize: + rect = QRect(self._position, QSize(width, 2000)) + flags = ( + Qt.AlignmentFlag.AlignLeft + | Qt.AlignmentFlag.AlignBaseline + | Qt.TextFlag.TextWordWrap + ) fm = QFontMetrics(self._font) bounding = fm.boundingRect(rect, flags, self._text) size = bounding.size() @@ -78,70 +94,80 @@ class Fragment: def height(self, width: int) -> int: return self.size(width).height() - def width(self, width:int) -> int: + def width(self, width: int) -> int: return self.size(width).width() - + def __repr__(self) -> str: - return f'({self._position.x()}, {self._position.y()}): {self._text}' - - def repaintEvent(self, painter:QPainter) -> int: + return f"({self._position.x()}, {self._position.y()}): {self._text}" + + def repaintEvent(self, painter: QPainter) -> int: painter.save() painter.setFont(self._font) painter.setPen(self._color) rect = QRect() rect.setLeft(self._position.x()) - rect.setTop(self._position.y() + painter.fontMetrics().descent() - painter.fontMetrics().height()) + rect.setTop( + self._position.y() + + painter.fontMetrics().descent() + - painter.fontMetrics().height() + ) rect.setWidth(painter.viewport().width() - self._position.x()) rect.setHeight(2000) - flags = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignBaseline | Qt.TextFlag.TextWordWrap - bounding = painter.boundingRect(rect,flags, self._text) + flags = ( + Qt.AlignmentFlag.AlignLeft + | Qt.AlignmentFlag.AlignBaseline + | Qt.TextFlag.TextWordWrap + ) + bounding = painter.boundingRect(rect, flags, self._text) size = bounding.size() painter.setPen(QColor("#f00")) if self._audio.isValid(): - radius = self._borderRect.height() /2 + radius = self._borderRect.height() / 2 painter.drawRoundedRect(self._borderRect, radius, radius) if self._wref: start = bounding.bottomLeft() end = bounding.bottomRight() - painter.drawLine(start,end) + painter.drawLine(start, end) painter.setPen(self._color) - painter.drawText( - rect, - flags, - self._text - ) + painter.drawText(rect, flags, self._text) painter.restore() size = size.grownBy(self._margin) size = size.grownBy(self._border) size = size.grownBy(self._padding) return size.height() + # # Setters # - def setText(self, text:str) -> None: + def setText(self, text: str) -> None: self._text = text return - def setFont(self, font:QFont) -> None: + + def setFont(self, font: QFont) -> None: self._font = font return - def setAudio(self, audio:str|QUrl) -> None: + + def setAudio(self, audio: str | QUrl) -> None: if type(audio) is str: self._audio = QUrl(audio) else: - self._audio = cast(QUrl,audio) + self._audio = cast(QUrl, audio) return - def setAlign(self, align:QTextOption) -> None: + + def setAlign(self, align: QTextOption) -> None: self._align = align return - def setRect(self,rect:QRect) -> None: + + def setRect(self, rect: QRect) -> None: self._rect = rect return - def setPadding(self, *args:int, **kwargs:int) -> None: - top = kwargs.get('top', -1) - right = kwargs.get('right', -1) - bottom = kwargs.get('bottom', -1) - left = kwargs.get('left', -1) + + def setPadding(self, *args: int, **kwargs: int) -> None: + top = kwargs.get("top", -1) + right = kwargs.get("right", -1) + bottom = kwargs.get("bottom", -1) + left = kwargs.get("left", -1) if top > -1 or right > -1 or bottom > -1 or left > -1: if top >= 0: self._padding.setTop(top) @@ -164,12 +190,12 @@ class Fragment: raise Exception("argument error") self._padding = QMargins(left, top, right, bottom) return - - def setBorder(self, *args:int, **kwargs:int) -> None: - top = kwargs.get('top', -1) - right = kwargs.get('right', -1) - bottom = kwargs.get('bottom', -1) - left = kwargs.get('left', -1) + + def setBorder(self, *args: int, **kwargs: int) -> None: + top = kwargs.get("top", -1) + right = kwargs.get("right", -1) + bottom = kwargs.get("bottom", -1) + left = kwargs.get("left", -1) if top > -1 or right > -1 or bottom > -1 or left > -1: if top >= 0: self._border.setTop(top) @@ -192,12 +218,13 @@ class Fragment: raise Exception("argument error") self._border = QMargins(left, top, right, bottom) return - def setMargin(self, *args:int, **kwargs:int) -> None: - top = kwargs.get('top', -1) - right = kwargs.get('right', -1) - bottom = kwargs.get('bottom', -1) - left = kwargs.get('left', -1) - + + def setMargin(self, *args: int, **kwargs: int) -> None: + top = kwargs.get("top", -1) + right = kwargs.get("right", -1) + bottom = kwargs.get("bottom", -1) + left = kwargs.get("left", -1) + if top > -1 or right > -1 or bottom > -1 or left > -1: if top >= 0: self._margin.setTop(top) @@ -209,7 +236,7 @@ class Fragment: self._margin.setLeft(left) return if len(args) == 4: - (top, right, bottom, left) =[args[0], args[1], args[2], args[3]] + (top, right, bottom, left) = [args[0], args[1], args[2], args[3]] elif len(args) == 3: (top, right, bottom, left) = [args[0], args[1], args[2], args[1]] elif len(args) == 2: @@ -220,58 +247,79 @@ class Fragment: raise Exception("argument error") self._margin = QMargins(left, top, right, bottom) return - def setWRef(self, ref:str) -> None: + + def setWRef(self, ref: str) -> None: self._wref = ref return - def setPosition(self, pnt:QPoint) -> None: + + def setPosition(self, pnt: QPoint) -> None: self._position = pnt return - def setBorderRect(self, rect:QRect) -> None: + + def setBorderRect(self, rect: QRect) -> None: self._borderRect = rect return - def setClickRect(self, rect:QRect) -> None: + + def setClickRect(self, rect: QRect) -> None: self._clickRect = rect return - def setColor(self,color:QColor) -> None: + + def setColor(self, color: QColor) -> None: self._color = color return - def setLeft(self, left:int) -> None: + + def setLeft(self, left: int) -> None: self._left = left return + # # Getters # def wRef(self) -> str: return self._wref + def text(self) -> str: return self._text + def font(self) -> QFont: return self._font + def audio(self) -> QUrl: return self._audio + def align(self) -> QTextOption: return self._align + def rect(self) -> QRect: return self._rect + def padding(self) -> QMargins: return self._padding + def border(self) -> QMargins: return self._border + def margin(self) -> QMargins: return self._margin + def position(self) -> QPoint: return self._position + def borderRect(self) -> QRect: return self._borderRect + def clickRect(self) -> QRect: return self._clickRect + def color(self) -> QColor: return self._color + def asis(self) -> bool: return self._asis + def left(self) -> int: return self._left - + API = "https://api.dictionaryapi.dev/api/v2/entries/en/{word}" MWAPI = "https://www.dictionaryapi.com/api/v3/references/collegiate/json/{word}?key=51d9df34-ee13-489e-8656-478c215e846c" @@ -280,21 +328,22 @@ MWAPI = "https://www.dictionaryapi.com/api/v3/references/collegiate/json/{word}? class Word: """All processing of a dictionary word.""" - _words: dict[str, Any] = {} class Line: - def __init__(self) -> None: self._maxHeight = -1 self._baseLine = -1 self._leading = -1 - self._fragments:list[Fragment] = [] + self._fragments: list[Fragment] = [] return def __repr__(self) -> str: - return '|'.join([x.text() for x in self._fragments])+f'|{self._maxHeight}' - + return ( + "|".join([x.text() for x in self._fragments]) + + f"|{self._maxHeight}" + ) + def repaintEvent(self, painter: QPainter) -> int: # # we do not have an event field because we are not a true widget @@ -320,12 +369,12 @@ class Word: smallCaps = QFont(frag.font()) smallCaps.setCapitalization(QFont.Capitalization.SmallCaps) script = QFont(frag.font()) - script.setPixelSize(int(script.pixelSize()/4)) + script.setPixelSize(int(script.pixelSize() / 4)) results: list[Fragment] = [] while True: text = frag.text() - start = text.find('{') + start = text.find("{") if start < 0: results.append(frag) return results @@ -342,84 +391,107 @@ class Word: # # If the token is an end-token, return now. # - if text.startswith('{/'): + if text.startswith("{/"): results.append(frag) return results # # extract this token # - end = text.find('}') + end = text.find("}") token = text[1:end] - frag.setText(text[end+1:]) + frag.setText(text[end + 1 :]) newFrag = copy.copy(frag) oldFont = QFont(frag.font()) - if token == 'bc': - results.append(Fragment(': ', bold, color=QColor('#fff'))) + if token == "bc": + results.append(Fragment(": ", bold, color=QColor("#fff"))) continue - if token in ['b', 'inf', 'it', 'sc', 'sup', 'phrase', 'parahw', 'gloss', - 'qword', 'wi', 'dx', 'dx_def', 'dx_ety', 'ma']: - if token == 'b': + if token in [ + "b", + "inf", + "it", + "sc", + "sup", + "phrase", + "parahw", + "gloss", + "qword", + "wi", + "dx", + "dx_def", + "dx_ety", + "ma", + ]: + if token == "b": frag.setFont(bold) - elif token in ['it', 'qword', 'wi']: + elif token in ["it", "qword", "wi"]: frag.setFont(italic) - elif token == 'sc': + elif token == "sc": frag.setFont(smallCaps) - elif token in ['inf', 'sup']: + elif token in ["inf", "sup"]: frag.setFont(script) - elif token == 'phrase': + elif token == "phrase": font = QFont(bold) font.setItalic(True) frag.setFont(font) - elif token == 'parahw': + elif token == "parahw": font = QFont(smallCaps) font.setWeight(QFont.Weight.Bold) frag.setFont(font) - elif token == 'gloss': - frag.setText('[' + frag.text()) - elif token in ['dx', 'dx_ety']: - frag.setText('\u2014'+frag.text()) - elif token == 'ma': - frag.setText('\u2014 more at '+frag.text()) - elif token == 'dx_def': - frag.setText('('+frag.text()) + elif token == "gloss": + frag.setText("[" + frag.text()) + elif token in ["dx", "dx_ety"]: + frag.setText("\u2014" + frag.text()) + elif token == "ma": + frag.setText("\u2014 more at " + frag.text()) + elif token == "dx_def": + frag.setText("(" + frag.text()) else: raise Exception(f"Unknown block marker: {token}") results += self.parseText(frag) frag = results.pop() frag.setFont(oldFont) text = frag.text() - if not text.startswith('{/'+token+'}'): - raise Exception(f"No matching close for {token} in {org}") - if token == 'gloss': - results[-1].setText(results[-1].text() + ']') - elif token == 'dx_def': - results[-1].setText(results[-1].text() + ')') - end = text.find('}') - text = text[end+1:] + if not text.startswith("{/" + token + "}"): + raise Exception( + f"No matching close for {token} in {org}" + ) + if token == "gloss": + results[-1].setText(results[-1].text() + "]") + elif token == "dx_def": + results[-1].setText(results[-1].text() + ")") + end = text.find("}") + text = text[end + 1 :] frag.setText(text) continue # # These are codes that include all information within the token # - fields = token.split('|') + fields = token.split("|") token = fields[0] - if token in [ 'a_line', 'd_link', 'dxt', 'et_link', 'i_link', - 'mat', 'sx']: - wref = '' + if token in [ + "a_line", + "d_link", + "dxt", + "et_link", + "i_link", + "mat", + "sx", + ]: + wref = "" htext = fields[1] oldFont = QFont(frag.font()) - if token == 'a_link': + if token == "a_link": wref = fields[1] - elif token in ['d_link', 'et_link', 'mat', 'sx', 'i_link']: - if fields[2] == '': + elif token in ["d_link", "et_link", "mat", "sx", "i_link"]: + if fields[2] == "": wref = fields[1] else: wref = fields[2] - if token == 'i_link': + if token == "i_link": frag.setFont(italic) - elif token == 'i_link': - if fields[2] == '': + elif token == "i_link": + if fields[2] == "": wref = fields[1] else: wref = fields[2] @@ -432,14 +504,18 @@ class Word: frag.setFont(oldFont) text = frag.text() continue - raise Exception(f"Unable to locate a known token {token} in {org}") + raise Exception( + f"Unable to locate a known token {token} in {org}" + ) - - def addFragment(self, frag: Fragment,) -> None: + def addFragment( + self, + frag: Fragment, + ) -> None: SPEAKER = "\U0001F508" if frag.audio().isValid(): - frag.setText(frag.text() + ' ' + SPEAKER) + frag.setText(frag.text() + " " + SPEAKER) text = frag.text() text = re.sub(r"\*", "\u2022", text) @@ -447,14 +523,14 @@ class Word: text = re.sub(r"\{rdquo\}", "\u201d", text) frag.setText(text) if frag.audio().isValid(): - frag.setPadding(3,0,0,5) + frag.setPadding(3, 0, 0, 5) frag.setBorder(1) - frag.setMargin(0,0,0,0) + frag.setMargin(0, 0, 0, 0) items = self.parseText(frag) self._fragments += items return - def finalizeLine(self, width: int, base:int ) -> None: + def finalizeLine(self, width: int, base: int) -> None: """Create all of the positions for all the fragments.""" # # Find the maximum hight and max baseline @@ -486,8 +562,12 @@ class Word: # size = frag.size(width) fm = QFontMetrics(frag.font()) - offset = frag.margin().left() + frag.border().left() + frag.padding().left() - frag.setPosition(QPoint(x+offset, self._baseLine)) + offset = ( + frag.margin().left() + + frag.border().left() + + frag.padding().left() + ) + frag.setPosition(QPoint(x + offset, self._baseLine)) if not frag.border().isNull() or not frag.wRef(): # # self._baseLine is where the text will be drawn @@ -497,16 +577,16 @@ class Word: # + fm.descent - rect.height # The border is drawn at top-padding-border-margin+marin # - top = self._baseLine + fm.descent() - fm.height() + top = self._baseLine + fm.descent() - fm.height() y = top - frag.padding().top() - frag.border().top() pos = QPoint(x, y) rect = QRect(pos, size.shrunkBy(frag.margin())) frag.setBorderRect(rect) - pos.setY(pos.y()+base) + pos.setY(pos.y() + base) frag.setClickRect(QRect(pos, size.shrunkBy(frag.margin()))) x += size.width() return - + def getLine(self) -> list[Fragment]: return self._fragments @@ -532,9 +612,9 @@ class Word: query_error(query) if query.next(): Word._words[word] = { - 'word': word, - 'source': query.value('source'), - 'definition': json.loads(query.value("definition")), + "word": word, + "source": query.value("source"), + "definition": json.loads(query.value("definition")), } self.current = Word._words[word] return @@ -556,30 +636,30 @@ class Word: data = json.loads(content.data().decode("utf-8")) print(data) self._words[word] = { - 'word': word, - 'source': source, - 'definition': data, - } + "word": word, + "source": source, + "definition": data, + } self.current = Word._words[word] query.prepare( "INSERT INTO words " "(word, source, definition) " "VALUES (:word, :source, :definition)" ) - query.bindValue(":word", self.current['word']) - query.bindValue(":source", self.current['source']) - query.bindValue(":definition", json.dumps(self.current['definition'])) + query.bindValue(":word", self.current["word"]) + query.bindValue(":source", self.current["source"]) + query.bindValue(":definition", json.dumps(self.current["definition"])) if not query.exec(): query_error(query) return def getWord(self) -> str: - return self.current['word'] + return self.current["word"] def get_html(self) -> str | None: - if self.current['source'] == 'mw': + if self.current["source"] == "mw": return self.mw_html() - elif self.current['source'] == 'apidictionary': + elif self.current["source"] == "apidictionary": return self.apidictionary_html() else: raise Exception(f"Unknown source: {self.current['source']}") @@ -603,170 +683,186 @@ class Word: headerFont.setWeight(QFont.Weight.Bold) boldFont.setBold(True) italicFont.setItalic(True) - + phonicFont = QFontDatabase.font("Gentium", None, 10) phonicFont.setPixelSize(20) - + self.resources = { - 'colors': { - 'base':QColor(Qt.GlobalColor.white), - 'blue': QColor("#4a7d95"), - }, - 'fonts': { - 'header': headerFont, - 'label': labelFont, - 'phonic': phonicFont, - 'bold': boldFont, - 'italic': italicFont, - 'text': textFont, - } + "colors": { + "base": QColor(Qt.GlobalColor.white), + "blue": QColor("#4a7d95"), + }, + "fonts": { + "header": headerFont, + "label": labelFont, + "phonic": phonicFont, + "bold": boldFont, + "italic": italicFont, + "text": textFont, + }, } - if self.current['source'] == 'mw': + if self.current["source"] == "mw": return self.mw_def() - elif self.current['source'] == 'apidictionary': + elif self.current["source"] == "apidictionary": return None else: raise Exception(f"Unknown source: {self.current['source']}") def mw_def(self) -> list[Line]: lines: list[Word.Line] = [] - for entry in self.current['definition']: - line = Word.Line() - meta = json.dumps(entry['meta']) - line.addFragment( - Fragment( - meta, - self.resources['fonts']['text'],asis=True - ) - ) - lines.append(line) + for entry in self.current["definition"]: lines += self.mw_def_entry(entry) self._lines = lines return lines def mw_seq(self, seq: list[Any]) -> list[Line]: lines: list[Word.Line] = [] - outer = ' ' - inner = ' ' + outer = " " + inner = " " for value in seq: sense = value[1] # # The optional 'sn' field tells us what sort of labeling to do # - sn = sense.get('sn', '') - sns = sn.split(' ') + sn = sense.get("sn", "") + sns = sn.split(" ") if len(sns) == 2: outer = sns[0] inner = sns[1] elif len(sns) == 1: - if inner == ' ': + if inner == " ": outer = sns[0] else: inner = sns[0] - for dt in sense['dt']: - if dt[0] == 'text': + for dt in sense["dt"]: + if dt[0] == "text": line = Word.Line() frag = Fragment( f"{outer} {inner} ", - self.resources['fonts']['bold'], - color = self.resources['colors']['base'] + self.resources["fonts"]["bold"], + color=self.resources["colors"]["base"], ) - outer = ' ' + outer = " " frag.setLeft(10) line.addFragment(frag) frag = Fragment( dt[1], - self.resources['fonts']['text'], - color = self.resources['colors']['base'] + self.resources["fonts"]["text"], + color=self.resources["colors"]["base"], ) frag.setLeft(30) line.addFragment(frag) lines.append(line) - elif dt[0] == 'vis': + elif dt[0] == "vis": for vis in dt[1]: line = Word.Line() - frag =Fragment(f" ", - self.resources['fonts']['bold'], - ) + frag = Fragment( + f" ", + self.resources["fonts"]["bold"], + ) frag.setLeft(45) line.addFragment(frag) line.addFragment( - Fragment(vis['t'], - self.resources['fonts']['text'], - color = QColor('#aaa') - ) + Fragment( + vis["t"], + self.resources["fonts"]["text"], + color=QColor("#aaa"), + ) ) lines.append(line) return lines + def mw_def_entry(self, entry) -> list[Line]: # # Easy reference to colors # - base = self.resources['colors']['base'] - blue = self.resources['colors']['blue'] + base = self.resources["colors"]["base"] + blue = self.resources["colors"]["blue"] lines: list[Word.Line] = [] line = Word.Line() - hw = re.sub(r'\*', '', entry['hwi']['hw']) - frag = Fragment(hw, self.resources['fonts']['header'], color=base) + hw = re.sub(r"\*", "", entry["hwi"]["hw"]) + frag = Fragment(hw, self.resources["fonts"]["header"], color=base) line.addFragment(frag) - frag = Fragment(' '+entry["fl"], self.resources['fonts']['label'], color=blue) + frag = Fragment( + " " + entry["fl"], self.resources["fonts"]["label"], color=blue + ) line.addFragment(frag) lines.append(line) if "vrs" in entry.keys(): line = self.Line() - space = '' + space = "" for vrs in entry["vrs"]: - frag = Fragment(space + vrs["va"], self.resources['fonts']['label'], color=base) - space = ' ' + frag = Fragment( + space + vrs["va"], + self.resources["fonts"]["label"], + color=base, + ) + space = " " line.addFragment(frag) lines.append(line) if "prs" in entry["hwi"].keys(): line = self.Line() - frag = Fragment(entry['hwi']['hw'] + ' ', self.resources['fonts']['phonic'], color=base) + frag = Fragment( + entry["hwi"]["hw"] + " ", + self.resources["fonts"]["phonic"], + color=base, + ) line.addFragment(frag) for prs in entry["hwi"]["prs"]: audio = self.mw_sound_url(prs) if audio is None: audio = "" - frag = Fragment(prs['mw'], self.resources['fonts']['phonic'], color=blue) + frag = Fragment( + prs["mw"], self.resources["fonts"]["phonic"], color=blue + ) frag.setAudio(audio) line.addFragment(frag) lines.append(line) if "ins" in entry.keys(): line = self.Line() - space = '' - for ins in entry['ins']: + space = "" + for ins in entry["ins"]: try: - frag = Fragment(ins['il'], self.resources['fonts']['text'], color=base) + frag = Fragment( + ins["il"], self.resources["fonts"]["text"], color=base + ) line.addFragment(frag) - space = ' ' + space = " " except KeyError: pass - frag = Fragment(space + ins['if'], self.resources['fonts']['bold'], color=base) + frag = Fragment( + space + ins["if"], + self.resources["fonts"]["bold"], + color=base, + ) line.addFragment(frag) - space = '; ' + space = "; " lines.append(line) - if 'lbs' in entry.keys(): + if "lbs" in entry.keys(): line = self.Line() - frag = Fragment('; '.join(entry['lbs']), self.resources['fonts']['bold'], color=base) + frag = Fragment( + "; ".join(entry["lbs"]), + self.resources["fonts"]["bold"], + color=base, + ) line.addFragment(frag) lines.append(line) - for value in entry['def']: # has multiple 'sseg' or 'vd' init - for k,v in value.items(): - if k == 'sseq': # has multiple 'senses' + for value in entry["def"]: # has multiple 'sseg' or 'vd' init + for k, v in value.items(): + if k == "sseq": # has multiple 'senses' for seq in v: r = self.mw_seq(seq) lines += r - elif k == 'vd': + elif k == "vd": line = self.Line() - line.addFragment(Fragment( - v, - self.resources['fonts']['italic'], - color=blue - )) + line.addFragment( + Fragment( + v, self.resources["fonts"]["italic"], color=blue + ) + ) lines.append(line) return lines @@ -867,13 +963,13 @@ class Definition(QWidget): def __init__(self, w: Word, *args: Any, **kwargs: Any) -> None: super(Definition, self).__init__(*args, **kwargs) - self._word:str = w.getWord() + self._word: str = w.getWord() lines = w.get_def() assert lines is not None self._lines = lines - self._buttons:list[Fragment] = [] + self._buttons: list[Fragment] = [] base = 0 - + for line in self._lines: line.finalizeLine(self.width(), base) for frag in line.getLine(): @@ -889,18 +985,18 @@ class Definition(QWidget): def resizeEvent(self, event: QResizeEvent) -> None: base = 0 for line in self._lines: - line.finalizeLine(self.width(),base) + line.finalizeLine(self.width(), base) base += line.getLineSpacing() self.setFixedHeight(base) - super(Definition,self).resizeEvent(event) + super(Definition, self).resizeEvent(event) return - - _downFrag: Optional[Fragment|None] = None + + _downFrag: Optional[Fragment | None] = None def mousePressEvent(self, event: Optional[QMouseEvent]) -> None: if not event: return super().mousePressEvent(event) - print(f'mousePressEvent: {event.pos()}') + print(f"mousePressEvent: {event.pos()}") for frag in self._buttons: rect = frag.clickRect() if rect.contains(event.pos()): @@ -911,11 +1007,13 @@ class Definition(QWidget): def mouseReleaseEvent(self, event: Optional[QMouseEvent]) -> None: if not event: return super().mouseReleaseEvent(event) - if self._downFrag is not None and self._downFrag.clickRect().contains(event.pos()): + if self._downFrag is not None and self._downFrag.clickRect().contains( + event.pos() + ): audio = self._downFrag.audio().url() print(audio) self.pronounce.emit(audio) - print('emit done') + print("emit done") self._downFrag = None return self._downFrag = None @@ -945,13 +1043,12 @@ class Definition(QWidget): painter.restore() return + class DefinitionArea(QScrollArea): def __init__(self, w: Word, *args: Any, **kwargs: Any) -> None: - super(DefinitionArea,self).__init__(*args,*kwargs) + super(DefinitionArea, self).__init__(*args, *kwargs) d = Definition(w) self.setWidget(d) self.setWidgetResizable(True) - self.setVerticalScrollBarPolicy( - Qt.ScrollBarPolicy.ScrollBarAlwaysOn - ) + self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn) return