-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathblock_controller.py
More file actions
78 lines (59 loc) · 2.58 KB
/
Copy pathblock_controller.py
File metadata and controls
78 lines (59 loc) · 2.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
"""Controller for handling block-related business logic."""
from __future__ import annotations
from typing import TYPE_CHECKING, List
from PyQt6.QtCore import QCoreApplication, QObject, QRunnable, QThreadPool, pyqtSignal
from block_events import AnalysisResultEvent, RhymeSyllableResult
from rhyme import rhyme_marks_for_block
from syllables import count_syllables
if TYPE_CHECKING:
from model import Block, Project
class AnalysisWorker(QRunnable):
"""Worker to perform text analysis in a background thread."""
def __init__(self, block_id: str, lines: List[str], target_widget: QObject) -> None:
super().__init__()
self.block_id = block_id
self.lines = lines
self.target_widget = target_widget
def run(self) -> None:
"""Execute the analysis."""
syllable_counts = [count_syllables(line) for line in self.lines]
rhyme_marks = rhyme_marks_for_block(self.lines)
result = RhymeSyllableResult(syllable_counts, rhyme_marks)
event = AnalysisResultEvent(self.block_id, result)
QCoreApplication.postEvent(self.target_widget, event)
class BlockController(QObject):
"""Manages business logic for blocks, decoupled from widgets."""
def __init__(self, project: Project, parent: QObject | None = None) -> None:
"""Initialize the controller.
Args:
project: The main project model.
parent: The parent QObject.
"""
super().__init__(parent)
self._project = project
self._thread_pool = QThreadPool()
self._thread_pool.setMaxThreadCount(2)
def get_verse_number(self, block: Block) -> int:
"""Calculates the sequential index of a verse block within the project.
Args:
block: The block to get the verse number for.
Returns:
The 1-based index of the verse.
"""
if block.section != "Verse" or block.kind == "instrumental":
return 1
verse_index = 0
for b in self._project.blocks:
if b.section == "Verse" and b.kind != "instrumental":
verse_index += 1
if b.id == block.id:
return verse_index
return verse_index
def request_analysis(self, block: Block, target_widget: QObject) -> None:
"""Request an asynchronous analysis of a block's text.
Args:
block: The block to analyze.
target_widget: The widget to post the result event to.
"""
worker = AnalysisWorker(block.id, list(block.lines), target_widget)
self._thread_pool.start(worker)