Add clocks to shared class and add search cache clearing

This commit is contained in:
Veronica Berglyd Olsen
2024-03-25 18:13:05 +01:00
parent 01a4ec8d76
commit 8a12b03a1f
4 changed files with 55 additions and 34 deletions
+31 -12
View File
@@ -23,9 +23,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
""" """
from __future__ import annotations from __future__ import annotations
import time
import logging import logging
from time import time
from PyQt5.QtCore import QSize, Qt, pyqtSignal, pyqtSlot from PyQt5.QtCore import QSize, Qt, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QKeyEvent, QPalette from PyQt5.QtGui import QKeyEvent, QPalette
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
@@ -40,6 +41,8 @@ from novelwriter.core.item import NWItem
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
CACHE_TIMEOUT = 120.0 # 2 minutes
class GuiProjectSearch(QWidget): class GuiProjectSearch(QWidget):
@@ -50,8 +53,8 @@ class GuiProjectSearch(QWidget):
D_HANDLE = Qt.ItemDataRole.UserRole D_HANDLE = Qt.ItemDataRole.UserRole
D_RESULT = Qt.ItemDataRole.UserRole + 1 D_RESULT = Qt.ItemDataRole.UserRole + 1
openDocumentSelectRequest = pyqtSignal(str, int, int, bool)
selectedItemChanged = pyqtSignal(str) selectedItemChanged = pyqtSignal(str)
openDocumentSelectRequest = pyqtSignal(str, int, int, bool)
def __init__(self, parent: QWidget) -> None: def __init__(self, parent: QWidget) -> None:
super().__init__(parent=parent) super().__init__(parent=parent)
@@ -61,7 +64,9 @@ class GuiProjectSearch(QWidget):
iPx = SHARED.theme.baseIconSize iPx = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(2) mPx = CONFIG.pxInt(2)
self._time = time()
self._search = DocSearch() self._search = DocSearch()
self._blocked = False
# Header # Header
self.viewLabel = QLabel(self.tr("Project Search")) self.viewLabel = QLabel(self.tr("Project Search"))
@@ -130,6 +135,8 @@ class GuiProjectSearch(QWidget):
self.setLayout(self.outerBox) self.setLayout(self.outerBox)
self.updateTheme() self.updateTheme()
SHARED.slowClockTick.connect(self._cacheTimeout)
logger.debug("Ready: GuiProjectSearch") logger.debug("Ready: GuiProjectSearch")
return return
@@ -205,7 +212,8 @@ class GuiProjectSearch(QWidget):
@pyqtSlot(str) @pyqtSlot(str)
def clearSearchCache(self, tHandle: str) -> None: def clearSearchCache(self, tHandle: str) -> None:
"""Process document content change.""" """Process document content change."""
self._search.clearTextCache(tHandle) if not self._blocked:
self._search.clearTextCache(tHandle)
return return
## ##
@@ -215,15 +223,19 @@ class GuiProjectSearch(QWidget):
@pyqtSlot() @pyqtSlot()
def _processSearch(self) -> None: def _processSearch(self) -> None:
"""Perform a search.""" """Perform a search."""
start = time.time() if not self._blocked:
self.searchResult.clear() start = time()
if text := self.searchText.text(): self._blocked = True
self._search.setUserRegEx(self.toggleRegEx.isChecked()) self.searchResult.clear()
self._search.setCaseSensitive(self.toggleCase.isChecked()) if text := self.searchText.text():
self._search.setWholeWords(self.toggleWord.isChecked()) self._search.setUserRegEx(self.toggleRegEx.isChecked())
for item, results, capped in self._search.iterSearch(SHARED.project, text): self._search.setCaseSensitive(self.toggleCase.isChecked())
self._appendResultSet(item, results, capped) self._search.setWholeWords(self.toggleWord.isChecked())
logger.debug("Search took %.3f ms", 1000*(time.time() - start)) for item, results, capped in self._search.iterSearch(SHARED.project, text):
self._appendResultSet(item, results, capped)
logger.debug("Search took %.3f ms", 1000*(time() - start))
self._time = time()
self._blocked = False
return return
@pyqtSlot() @pyqtSlot()
@@ -272,6 +284,13 @@ class GuiProjectSearch(QWidget):
CONFIG.searchProjRegEx = state CONFIG.searchProjRegEx = state
return return
@pyqtSlot()
def _cacheTimeout(self) -> None:
"""Clear the cache after a period of inactivity."""
if not self._blocked and time() - self._time > CACHE_TIMEOUT:
self._search.clearTextCache(None)
return
## ##
# Internal Functions # Internal Functions
## ##
+10 -16
View File
@@ -220,6 +220,7 @@ class GuiMain(QMainWindow):
SHARED.indexScannedText.connect(self.itemDetails.updateViewBox) SHARED.indexScannedText.connect(self.itemDetails.updateViewBox)
SHARED.indexCleared.connect(self.docViewerPanel.indexWasCleared) SHARED.indexCleared.connect(self.docViewerPanel.indexWasCleared)
SHARED.indexAvailable.connect(self.docViewerPanel.indexHasAppeared) SHARED.indexAvailable.connect(self.docViewerPanel.indexHasAppeared)
SHARED.mainClockTick.connect(self._timeTick)
self.mainMenu.requestDocAction.connect(self._passDocumentAction) self.mainMenu.requestDocAction.connect(self._passDocumentAction)
self.mainMenu.requestDocInsert.connect(self._passDocumentInsert) self.mainMenu.requestDocInsert.connect(self._passDocumentInsert)
@@ -287,12 +288,6 @@ class GuiMain(QMainWindow):
self.asDocTimer = QTimer(self) self.asDocTimer = QTimer(self)
self.asDocTimer.timeout.connect(self._autoSaveDocument) self.asDocTimer.timeout.connect(self._autoSaveDocument)
# Main Clock
self.mainTimer = QTimer(self)
self.mainTimer.setInterval(1000)
self.mainTimer.timeout.connect(self._timeTick)
self.mainTimer.start()
# Shortcuts and Actions # Shortcuts and Actions
self._connectMenuActions() self._connectMenuActions()
@@ -1212,16 +1207,15 @@ class GuiMain(QMainWindow):
@pyqtSlot() @pyqtSlot()
def _timeTick(self) -> None: def _timeTick(self) -> None:
"""Process time tick of the main timer.""" """Process time tick of the main timer."""
if not SHARED.hasProject: if SHARED.hasProject:
return currTime = time()
currTime = time() editIdle = currTime - self.docEditor.lastActive > CONFIG.userIdleTime
editIdle = currTime - self.docEditor.lastActive > CONFIG.userIdleTime userIdle = qApp.applicationState() != Qt.ApplicationActive
userIdle = qApp.applicationState() != Qt.ApplicationActive self.mainStatus.setUserIdle(editIdle or userIdle)
self.mainStatus.setUserIdle(editIdle or userIdle) SHARED.updateIdleTime(currTime, editIdle or userIdle)
SHARED.updateIdleTime(currTime, editIdle or userIdle) self.mainStatus.updateTime(idleTime=SHARED.projectIdleTime)
self.mainStatus.updateTime(idleTime=SHARED.projectIdleTime) if CONFIG.memInfo and int(currTime) % 5 == 0: # pragma: no cover
if CONFIG.memInfo and int(currTime) % 5 == 0: # pragma: no cover self.mainStatus.memInfo()
self.mainStatus.memInfo()
return return
@pyqtSlot() @pyqtSlot()
+13 -1
View File
@@ -30,7 +30,7 @@ from time import time
from typing import TYPE_CHECKING, TypeVar from typing import TYPE_CHECKING, TypeVar
from pathlib import Path from pathlib import Path
from PyQt5.QtCore import QObject, QRunnable, QThreadPool, pyqtSignal from PyQt5.QtCore import QObject, QRunnable, QThreadPool, QTimer, pyqtSignal
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QWidget from PyQt5.QtWidgets import QFileDialog, QMessageBox, QWidget
from novelwriter.common import formatFileFilter from novelwriter.common import formatFileFilter
@@ -62,6 +62,8 @@ class SharedData(QObject):
indexChangedTags = pyqtSignal(list, list) indexChangedTags = pyqtSignal(list, list)
indexCleared = pyqtSignal() indexCleared = pyqtSignal()
indexAvailable = pyqtSignal() indexAvailable = pyqtSignal()
mainClockTick = pyqtSignal()
slowClockTick = pyqtSignal()
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() super().__init__()
@@ -79,6 +81,14 @@ class SharedData(QObject):
self._idleRefTime = time() self._idleRefTime = time()
self._focusMode = False self._focusMode = False
self._fClock = QTimer(self)
self._fClock.setInterval(1000)
self._fClock.timeout.connect(lambda: self.mainClockTick.emit())
self._sClock = QTimer(self)
self._sClock.setInterval(10000)
self._sClock.timeout.connect(lambda: self.slowClockTick.emit())
return return
## ##
@@ -158,6 +168,8 @@ class SharedData(QObject):
soon as the Main GUI is created to ensure the SHARED singleton soon as the Main GUI is created to ensure the SHARED singleton
has the properties needed for operation. has the properties needed for operation.
""" """
self._fClock.start()
self._sClock.start()
self._gui = gui self._gui = gui
self._theme = theme self._theme = theme
self._resetProject() self._resetProject()
+1 -5
View File
@@ -794,11 +794,7 @@ class _PreviewWidget(QTextBrowser):
self._updateDocMargins() self._updateDocMargins()
self._updateBuildAge() self._updateBuildAge()
# Age Timer SHARED.slowClockTick.connect(self._updateBuildAge)
self.ageTimer = QTimer(self)
self.ageTimer.setInterval(10)
self.ageTimer.timeout.connect(self._updateBuildAge)
self.ageTimer.start()
return return