diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index bc526608..9b4cd827 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -1139,7 +1139,7 @@ class GuiDocEditor(QPlainTextEdit): if time() - self._lastEdit < 5 * self.wcInterval: logger.debug("Running word counter") - self.mainGui.threadPool.start(self.wCounterDoc) + SHARED.runInThreadPool(self.wCounterDoc) return @@ -1192,7 +1192,7 @@ class GuiDocEditor(QPlainTextEdit): logger.debug("Selection word counter is busy") return - self.mainGui.threadPool.start(self.wCounterSel) + SHARED.runInThreadPool(self.wCounterSel) return diff --git a/novelwriter/gui/editordocument.py b/novelwriter/gui/editordocument.py index 40b15288..434f3914 100644 --- a/novelwriter/gui/editordocument.py +++ b/novelwriter/gui/editordocument.py @@ -51,10 +51,19 @@ class GuiTextDocument(QTextDocument): logger.debug("Delete: GuiTextDocument") return + ## + # Properties + ## + @property def syntaxHighlighter(self) -> GuiDocHighlighter: + """Return the document's syntax highlighter object.""" return self._syntax + ## + # Metods + ## + def setTextContent(self, text: str, tHandle: str) -> None: """Set the text content of the document.""" self._syntax.setHandle(tHandle) diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py index feafec69..b19f585f 100644 --- a/novelwriter/guimain.py +++ b/novelwriter/guimain.py @@ -30,7 +30,7 @@ from time import time from pathlib import Path from datetime import datetime -from PyQt5.QtCore import Qt, QTimer, QThreadPool, pyqtSlot +from PyQt5.QtCore import Qt, QTimer, pyqtSlot from PyQt5.QtGui import QCloseEvent, QCursor, QIcon, QKeySequence from PyQt5.QtWidgets import ( QDialog, QFileDialog, QHBoxLayout, QMainWindow, QMessageBox, QShortcut, @@ -95,7 +95,6 @@ class GuiMain(QMainWindow): logger.debug("Create: GUI") self.setObjectName("GuiMain") - self.threadPool = QThreadPool(self) # System Info # =========== diff --git a/novelwriter/shared.py b/novelwriter/shared.py index 2a186a75..b5e6d4fd 100644 --- a/novelwriter/shared.py +++ b/novelwriter/shared.py @@ -29,7 +29,7 @@ from time import time from typing import TYPE_CHECKING from pathlib import Path -from PyQt5.QtCore import QObject, pyqtSignal +from PyQt5.QtCore import QObject, QRunnable, QThreadPool, pyqtSignal from PyQt5.QtWidgets import QMessageBox, QWidget from novelwriter.core.spellcheck import NWSpellEnchant @@ -55,14 +55,23 @@ class SharedData(QObject): def __init__(self) -> None: super().__init__() + + # Objects self._gui = None self._theme = None self._project = None self._spelling = None + + # Settings self._lockedBy = None self._alert = None self._idleTime = 0.0 self._idleRefTime = time() + + # Threading + self._threadPool = QThreadPool(self) + self._threadPool.setMaxThreadCount(5) + return ## @@ -199,6 +208,11 @@ class SharedData(QObject): self.projectStatusChanged.emit(state) return + def runInThreadPool(self, runnable: QRunnable, priority: int = 0) -> None: + """Queue a runnable in the application thread pool.""" + self._threadPool.start(runnable, priority=priority) + return + ## # Alert Boxes ## diff --git a/tests/test_gui/test_gui_doceditor.py b/tests/test_gui/test_gui_doceditor.py index 8bee4ab4..276bafa5 100644 --- a/tests/test_gui/test_gui_doceditor.py +++ b/tests/test_gui/test_gui_doceditor.py @@ -1100,13 +1100,14 @@ def testGuiEditor_WordCounters(qtbot, monkeypatch, nwGUI, projPath, ipsumText, m def __init__(self): self._objID = None - def start(self, runObj): + def start(self, runObj, priority=0): self._objID = id(runObj) def objectID(self): return self._objID - nwGUI.threadPool = MockThreadPool() + threadPool = MockThreadPool() + monkeypatch.setattr(SHARED, "_threadPool", threadPool) nwGUI.docEditor.wcTimerDoc.blockSignals(True) nwGUI.docEditor.wcTimerSel.blockSignals(True) @@ -1145,7 +1146,7 @@ def testGuiEditor_WordCounters(qtbot, monkeypatch, nwGUI, projPath, ipsumText, m # Run the full word counter nwGUI.docEditor._runDocCounter() - assert nwGUI.threadPool.objectID() == id(nwGUI.docEditor.wCounterDoc) + assert SHARED._threadPool.objectID() == id(nwGUI.docEditor.wCounterDoc) nwGUI.docEditor.wCounterDoc.run() # nwGUI.docEditor._updateDocCounts(cC, wC, pC) @@ -1161,7 +1162,7 @@ def testGuiEditor_WordCounters(qtbot, monkeypatch, nwGUI, projPath, ipsumText, m # Run the selection word counter nwGUI.docEditor._runSelCounter() - assert nwGUI.threadPool.objectID() == id(nwGUI.docEditor.wCounterSel) + assert SHARED._threadPool.objectID() == id(nwGUI.docEditor.wCounterSel) nwGUI.docEditor.wCounterSel.run() # nwGUI.docEditor._updateSelCounts(cC, wC, pC)