From e52d8d9ff7dbdd7982dbd2124dcbda6f1425a143 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Mon, 14 Nov 2022 16:59:04 +0100 Subject: [PATCH] Add novel tree method to refresh metadata for item --- novelwriter/core/index.py | 5 +++ novelwriter/gui/doceditor.py | 14 +++++---- novelwriter/gui/noveltree.py | 60 ++++++++++++++++++++++++++++-------- novelwriter/guimain.py | 2 ++ 4 files changed, 62 insertions(+), 19 deletions(-) diff --git a/novelwriter/core/index.py b/novelwriter/core/index.py index bdd49925..cf9cc002 100644 --- a/novelwriter/core/index.py +++ b/novelwriter/core/index.py @@ -501,6 +501,11 @@ class NWIndex: yield f"{tHandle}:{sTitle}", tHandle, sTitle, hItem return + def getItemData(self, tHandle): + """Get the index data for a given item. + """ + return self._itemIndex[tHandle] + def getNovelWordCount(self, skipExcl=True): """Count the number of words in the novel project. """ diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index 1e2704f2..caa1b925 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -51,7 +51,7 @@ from PyQt5.QtWidgets import ( ) from novelwriter.core import NWSpellEnchant, countWords -from novelwriter.enum import nwAlert, nwDocAction, nwDocInsert, nwDocMode +from novelwriter.enum import nwAlert, nwDocAction, nwDocInsert, nwDocMode, nwItemClass from novelwriter.common import transferCase from novelwriter.constants import nwConst, nwFiles, nwKeyWords, nwUnicode from novelwriter.gui.dochighlight import GuiDocHighlighter @@ -71,6 +71,8 @@ class GuiDocEditor(QTextEdit): docEditedStatusChanged = pyqtSignal(bool) docCountsChanged = pyqtSignal(str, int, int, int) loadDocumentTagRequest = pyqtSignal(str, Enum) + novelStructureChanged = pyqtSignal() + novelItemMetaChanged = pyqtSignal(str) def __init__(self, mainGui): super().__init__(parent=mainGui) @@ -534,11 +536,11 @@ class GuiDocEditor(QTextEdit): self.theProject.index.scanText(tHandle, docText) newHeader = self._nwItem.mainHeading - # ToDo: This should be a signal - if self._updateHeaders(): - self.mainGui.requestNovelTreeRefresh() - else: - self.mainGui.novelView.updateWordCounts(tHandle) + if self._nwItem.itemClass == nwItemClass.NOVEL: + if self._updateHeaders(): + self.novelStructureChanged.emit() + else: + self.novelItemMetaChanged.emit(tHandle) # ToDo: This should be a signal if oldHeader != newHeader: diff --git a/novelwriter/gui/noveltree.py b/novelwriter/gui/noveltree.py index 02a7f567..e3134c8c 100644 --- a/novelwriter/gui/noveltree.py +++ b/novelwriter/gui/noveltree.py @@ -83,7 +83,6 @@ class GuiNovelView(QWidget): self.setLayout(self.outerBox) # Function Mappings - self.updateWordCounts = self.novelTree.updateWordCounts self.getSelectedHandle = self.novelTree.getSelectedHandle self.setActiveHandle = self.novelTree.setActiveHandle @@ -107,12 +106,6 @@ class GuiNovelView(QWidget): self.novelTree.initSettings() return - def refreshTree(self): - """Refresh the current tree. - """ - self.novelTree.refreshTree(rootHandle=self.theProject.data.getLastHandle("novelTree")) - return - def clearProject(self): """Clear project-related GUI content. """ @@ -164,6 +157,13 @@ class GuiNovelView(QWidget): # Public Slots ## + @pyqtSlot() + def refreshTree(self): + """Refresh the current tree. + """ + self.novelTree.refreshTree(rootHandle=self.theProject.data.getLastHandle("novelTree")) + return + @pyqtSlot(str) def updateRootItem(self, tHandle): """If any root item changes, rebuild the novel root menu. @@ -171,6 +171,14 @@ class GuiNovelView(QWidget): self.novelBar.buildNovelRootMenu() return + @pyqtSlot(str) + def updateNovelItemMeta(self, tHandle): + """The meta data of a novel item has changed, and the tree item + needs to be refreshed. + """ + self.novelTree.refreshHandle(tHandle) + return + # END Class GuiNovelView @@ -495,13 +503,39 @@ class GuiNovelTree(QTreeWidget): return - def updateWordCounts(self, tHandle): - """Update the word count for a given handle. + def refreshHandle(self, tHandle): + """Refresh the data for a given handle. """ - tHeaders = self.theProject.index.getHandleWordCounts(tHandle) - for titleKey, wCount in tHeaders: - if titleKey in self._treeMap: - self._treeMap[titleKey].setText(self.C_WORDS, f"{wCount:n}") + idxData = self.theProject.index.getItemData(tHandle) + if idxData is None: + return + + for sTitle, tHeading in idxData.items(): + sKey = f"{tHandle}:{sTitle}" + trItem = self._treeMap.get(sKey, None) + if trItem is None: + logger.debug("Heading '%s' not in novel tree", sKey) + continue + + iLevel = nwHeaders.H_LEVEL.get(tHeading.level, 0) + if iLevel == 0: + continue + + hDec = self.mainTheme.getHeaderDecoration(iLevel) + + trItem.setData(self.C_TITLE, Qt.DecorationRole, hDec) + trItem.setText(self.C_TITLE, tHeading.title) + trItem.setFont(self.C_TITLE, self._hFonts[iLevel]) + trItem.setText(self.C_WORDS, f"{tHeading.wordCount:n}") + trItem.setTextAlignment(self.C_WORDS, Qt.AlignRight) + trItem.setData(self.C_MORE, Qt.DecorationRole, self._pMore) + + # Custom column + lastText, toolTip = self._getLastColumnText(tHandle, sTitle) + trItem.setText(self.C_EXTRA, lastText) + if lastText: + trItem.setToolTip(self.C_EXTRA, toolTip) + return def getSelectedHandle(self): diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py index 6a25e528..c4b569e6 100644 --- a/novelwriter/guimain.py +++ b/novelwriter/guimain.py @@ -224,6 +224,8 @@ class GuiMain(QMainWindow): self.docEditor.docCountsChanged.connect(self.itemDetails.updateCounts) self.docEditor.docCountsChanged.connect(self.projView.updateCounts) self.docEditor.loadDocumentTagRequest.connect(self._followTag) + self.docEditor.novelStructureChanged.connect(self.novelView.refreshTree) + self.docEditor.novelItemMetaChanged.connect(self.novelView.updateNovelItemMeta) self.docViewer.loadDocumentTagRequest.connect(self._followTag)