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