diff --git a/novelwriter/core/index.py b/novelwriter/core/index.py index dc7ac20a..bf914e13 100644 --- a/novelwriter/core/index.py +++ b/novelwriter/core/index.py @@ -113,6 +113,7 @@ class NWIndex: self._itemIndex.clear() self._indexChange = 0.0 self._rootChange = {} + SHARED.indexCallBack({"event": "clearIndex"}) return def rebuildIndex(self) -> None: @@ -122,16 +123,22 @@ class NWIndex: if nwItem.isFileType(): tHandle = nwItem.itemHandle theDoc = self._project.storage.getDocument(tHandle) - self.scanText(tHandle, theDoc.readDocument() or "") + self.scanText(tHandle, theDoc.readDocument() or "", blockSignal=True) self._indexBroken = False + SHARED.indexCallBack({"event": "buildIndex"}) return def deleteHandle(self, tHandle: str) -> None: """Delete all entries of a given document handle.""" logger.debug("Removing item '%s' from the index", tHandle) - for tTag in self._itemIndex.allItemTags(tHandle): + delTags = self._itemIndex.allItemTags(tHandle) + for tTag in delTags: del self._tagsIndex[tTag] del self._itemIndex[tHandle] + SHARED.indexCallBack({ + "event": "updateTags", + "deleted": delTags, + }) return def reIndexHandle(self, tHandle: str | None) -> bool: @@ -139,14 +146,12 @@ class NWIndex: moved from the archive or trash folders back into the active project. """ - if tHandle is None or not self._project.tree.checkType(tHandle, nwItemType.FILE): - return False - - logger.debug("Re-indexing item '%s'", tHandle) - theDoc = self._project.storage.getDocument(tHandle) - self.scanText(tHandle, theDoc.readDocument() or "") - - return True + if tHandle and self._project.tree.checkType(tHandle, nwItemType.FILE): + logger.debug("Re-indexing item '%s'", tHandle) + theDoc = self._project.storage.getDocument(tHandle) + self.scanText(tHandle, theDoc.readDocument() or "") + return True + return False def indexChangedSince(self, checkTime: int | float) -> bool: """Check if the index has changed since a given time.""" @@ -201,6 +206,7 @@ class NWIndex: self.reIndexHandle(fHandle) self._indexChange = time() + SHARED.indexCallBack({"event": "buildIndex"}) logger.debug("Index loaded in %.3f ms", (time() - tStart)*1000) @@ -239,7 +245,7 @@ class NWIndex: # Index Building ## - def scanText(self, tHandle: str, text: str) -> bool: + def scanText(self, tHandle: str, text: str, blockSignal: bool = False) -> bool: """Scan a piece of text associated with a handle. This will update the indices accordingly. This function takes the handle and text as separate inputs as we want to primarily scan the @@ -283,7 +289,11 @@ class NWIndex: nowTime = time() self._indexChange = nowTime self._rootChange[tItem.itemRoot] = nowTime - SHARED.indexDocumentScanned(tHandle) + if not blockSignal: + SHARED.indexCallBack({ + "event": "scanText", + "handle": tHandle, + }) return True @@ -358,7 +368,11 @@ class NWIndex: del self._tagsIndex[tTag] deleted.append(tTag) if updated or deleted: - SHARED.indexUpdatedTags(updated, deleted) + SHARED.indexCallBack({ + "event": "updateTags", + "updated": updated, + "deleted": deleted, + }) return diff --git a/novelwriter/gui/docviewerpanel.py b/novelwriter/gui/docviewerpanel.py index eab63a42..9896dee8 100644 --- a/novelwriter/gui/docviewerpanel.py +++ b/novelwriter/gui/docviewerpanel.py @@ -103,30 +103,27 @@ class GuiDocViewerPanel(QWidget): return - def openProjectTasks(self) -> None: - """Run open project tasks.""" - self.clearClassTabs() - for key, name, tClass, iItem, hItem in SHARED.project.index.getTagsData(): - if tClass in self.kwTabs and iItem and hItem: - self.kwTabs[tClass].addUpdateEntry(key, name, iItem, hItem) - self._updateTabVisibility() - return + ## + # Public Slots + ## - def closeProjectTasks(self) -> None: - """Run closing project tasks.""" - self.tabBackRefs.refreshContent(None) - self.clearClassTabs() - return - - def clearClassTabs(self) -> None: - """Clear all the class tabs""" + @pyqtSlot() + def indexWasCleared(self) -> None: + """Handle event when the index has been cleared of content.""" + self.tabBackRefs.clearContent() for cTab in self.kwTabs.values(): cTab.clearContent() return - ## - # Public Slots - ## + @pyqtSlot() + def indexHasAppeared(self) -> None: + """Handle event when the index has appeared.""" + for key, name, tClass, iItem, hItem in SHARED.project.index.getTagsData(): + if tClass in self.kwTabs and iItem and hItem: + self.kwTabs[tClass].addUpdateEntry(key, name, iItem, hItem) + self._updateTabVisibility() + self.updateHandle(self._lastHandle) + return @pyqtSlot(str) def projectItemChanged(self, tHandle: str) -> None: @@ -218,10 +215,15 @@ class _ViewPanelBackRefs(QTreeWidget): return - def refreshContent(self, dHandle: str | None) -> None: - """Update the content.""" + def clearContent(self) -> None: + """Clear the widget.""" self.clear() self._treeMap = {} + return + + def refreshContent(self, dHandle: str | None) -> None: + """Update the content.""" + self.clearContent() if dHandle: refs = SHARED.project.index.getBackReferenceList(dHandle) for tHandle, (sTitle, hItem) in refs.items(): diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py index 68815c76..099cb422 100644 --- a/novelwriter/guimain.py +++ b/novelwriter/guimain.py @@ -244,9 +244,11 @@ class GuiMain(QMainWindow): SHARED.projectStatusMessage.connect(self.mainStatus.setStatusMessage) SHARED.spellLanguageChanged.connect(self.mainStatus.setLanguage) SHARED.indexChangedTags.connect(self.docViewerPanel.updateChangedTags) - SHARED.indexScannedDocument.connect(self.docViewerPanel.projectItemChanged) - SHARED.indexScannedDocument.connect(self.projView.updateItemValues) - SHARED.indexScannedDocument.connect(self.itemDetails.updateViewBox) + SHARED.indexScannedText.connect(self.docViewerPanel.projectItemChanged) + SHARED.indexScannedText.connect(self.projView.updateItemValues) + SHARED.indexScannedText.connect(self.itemDetails.updateViewBox) + SHARED.indexCleared.connect(self.docViewerPanel.indexWasCleared) + SHARED.indexAvailable.connect(self.docViewerPanel.indexHasAppeared) self.mainMenu.requestDocAction.connect(self._passDocumentAction) self.mainMenu.requestDocInsert.connect(self._passDocumentInsert) @@ -448,7 +450,6 @@ class GuiMain(QMainWindow): self.docViewer.clearNavHistory() self.closeDocViewer(byUser=False) - self.docViewerPanel.closeProjectTasks() self.outlineView.closeProjectTasks() self.novelView.closeProjectTasks() self.projView.clearProjectView() @@ -522,7 +523,6 @@ class GuiMain(QMainWindow): self.projView.openProjectTasks() self.novelView.openProjectTasks() self.outlineView.openProjectTasks() - self.docViewerPanel.openProjectTasks() self._updateStatusWordCount() # Restore previously open documents, if any @@ -816,7 +816,6 @@ class GuiMain(QMainWindow): tStart = time() self.projView.saveProjectTasks() - self.docViewerPanel.clearClassTabs() SHARED.project.index.rebuildIndex() self.projView.populateTree() self.novelView.refreshTree() diff --git a/novelwriter/shared.py b/novelwriter/shared.py index 8980a520..36b0bdaf 100644 --- a/novelwriter/shared.py +++ b/novelwriter/shared.py @@ -52,8 +52,10 @@ class SharedData(QObject): projectStatusChanged = pyqtSignal(bool) projectStatusMessage = pyqtSignal(str) spellLanguageChanged = pyqtSignal(str, str) - indexScannedDocument = pyqtSignal(str) + indexScannedText = pyqtSignal(str) indexChangedTags = pyqtSignal(list, list) + indexCleared = pyqtSignal() + indexAvailable = pyqtSignal() def __init__(self) -> None: super().__init__() @@ -216,14 +218,18 @@ class SharedData(QObject): # Call-Back Functions ## - def indexUpdatedTags(self, updated: list[str], deleted: list[str]) -> None: - """Emit the index changed tags signal.""" - self.indexChangedTags.emit(updated, deleted) - return - - def indexDocumentScanned(self, tHandle: str) -> None: - """Emit the index scanned document signal.""" - self.indexScannedDocument.emit(tHandle) + def indexCallBack(self, data: dict) -> None: + """Emit signals on behalf of the index.""" + event = data.get("event") + logger.debug("Received '%s' event from the index", event) + if event == "updateTags": + self.indexChangedTags.emit(data.get("updated", []), data.get("deleted", [])) + elif event == "scanText": + self.indexScannedText.emit(data.get("handle", "")) + elif event == "clearIndex": + self.indexCleared.emit() + elif event == "buildIndex": + self.indexAvailable.emit() return ##