From 069e3baf67814bdc45869c3f3ffb077264857b30 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sun, 31 Jul 2022 18:40:16 +0200 Subject: [PATCH] Add functionality to load and save last selected outline novel, and fix a few inconsistencies --- .../assets/icons/typicons_dark/icons.conf | 1 + .../assets/icons/typicons_light/icons.conf | 1 + novelwriter/core/project.py | 21 +++--- novelwriter/gui/outline.py | 69 ++++++++++++++----- novelwriter/gui/projtree.py | 3 - novelwriter/guimain.py | 21 ++---- sample/nwProject.nwx | 9 ++- 7 files changed, 68 insertions(+), 57 deletions(-) diff --git a/novelwriter/assets/icons/typicons_dark/icons.conf b/novelwriter/assets/icons/typicons_dark/icons.conf index f372c60c..568c5b24 100644 --- a/novelwriter/assets/icons/typicons_dark/icons.conf +++ b/novelwriter/assets/icons/typicons_dark/icons.conf @@ -84,6 +84,7 @@ view_editor = mixed_edit.svg view_novel = typ_book-grey.svg view_outline = typ_puzzle-outline.svg +deco_doc_h0 = nw_deco-h0.svg deco_doc_h1 = nw_deco-h1.svg deco_doc_h2 = nw_deco-h2.svg deco_doc_h3 = nw_deco-h3.svg diff --git a/novelwriter/assets/icons/typicons_light/icons.conf b/novelwriter/assets/icons/typicons_light/icons.conf index 4514eab9..1d6a6c0c 100644 --- a/novelwriter/assets/icons/typicons_light/icons.conf +++ b/novelwriter/assets/icons/typicons_light/icons.conf @@ -84,6 +84,7 @@ view_editor = mixed_edit.svg view_novel = typ_book-grey.svg view_outline = typ_puzzle-outline.svg +deco_doc_h0 = nw_deco-h0.svg deco_doc_h1 = nw_deco-h1.svg deco_doc_h2 = nw_deco-h2.svg deco_doc_h3 = nw_deco-h3.svg diff --git a/novelwriter/core/project.py b/novelwriter/core/project.py index fb81f033..4b470d69 100644 --- a/novelwriter/core/project.py +++ b/novelwriter/core/project.py @@ -97,7 +97,6 @@ class NWProject(): self.autoReplace = {} # Text to auto-replace on exports self.titleFormat = {} # The formatting of titles for exports self.spellCheck = False # Controls the spellcheck-as-you-type feature - self.autoOutline = True # If true, the Project Outline is updated automatically self.statusItems = None # Novel file progress status values self.importItems = None # Note file importance values self.lastEdited = None # The handle of the last file to be edited @@ -258,7 +257,6 @@ class NWProject(): "section": "", } self.spellCheck = False - self.autoOutline = True self.statusItems = NWStatus(NWStatus.STATUS) self.statusItems.write(None, self.tr("New"), (100, 100, 100)) self.statusItems.write(None, self.tr("Note"), (200, 50, 0)) @@ -608,8 +606,6 @@ class NWProject(): self.spellCheck = checkBool(xItem.text, False) elif xItem.tag == "spellLang": self.projSpell = checkString(xItem.text, None, True) - elif xItem.tag == "autoOutline": - self.autoOutline = checkBool(xItem.text, True) elif xItem.tag == "lastEdited": self.lastEdited = checkString(xItem.text, None, True) elif xItem.tag == "lastViewed": @@ -735,7 +731,6 @@ class NWProject(): self._packProjectValue(xSettings, "language", self.projLang) self._packProjectValue(xSettings, "spellCheck", self.spellCheck) self._packProjectValue(xSettings, "spellLang", self.projSpell) - self._packProjectValue(xSettings, "autoOutline", self.autoOutline) self._packProjectValue(xSettings, "lastEdited", self.lastEdited) self._packProjectValue(xSettings, "lastViewed", self.lastViewed) self._packProjectValue(xSettings, "lastNovel", self.lastNovel) @@ -1096,14 +1091,6 @@ class NWProject(): self.setProjectChanged(True) return True - def setAutoOutline(self, theMode): - """Enable/disable automatic update of project outline. - """ - if self.autoOutline != theMode: - self.autoOutline = theMode - self.setProjectChanged(True) - return self.autoOutline - def setTreeOrder(self, newOrder): """A list representing the linear/flattened order of project items in the GUI project tree. The user can rearrange the order @@ -1139,6 +1126,14 @@ class NWProject(): self.setProjectChanged(True) return True + def setLastOutlineViewed(self, tHandle): + """Set last viewed novel root in the outline view. + """ + if self.lastOutline != tHandle: + self.lastOutline = tHandle + self.setProjectChanged(True) + return True + def setStatusColours(self, newCols, delCols): """Update the list of novel file status flags. """ diff --git a/novelwriter/gui/outline.py b/novelwriter/gui/outline.py index 49efe5f0..7c35ebb7 100644 --- a/novelwriter/gui/outline.py +++ b/novelwriter/gui/outline.py @@ -59,8 +59,9 @@ class GuiOutlineView(QWidget): def __init__(self, mainGui): QWidget.__init__(self, mainGui) - self.mainConf = novelwriter.CONFIG - self.mainGui = mainGui + self.mainConf = novelwriter.CONFIG + self.mainGui = mainGui + self.theProject = mainGui.theProject # Build GUI self.outlineBar = GuiOutlineToolBar(self) @@ -96,26 +97,43 @@ class GuiOutlineView(QWidget): # Methods ## - def splitSizes(self): - return self.splitOutline.sizes() - - def clearOutline(self): - self.outlineData.clearDetails() - return - def initOutline(self): self.outlineTree.initOutline() self.outlineData.initDetails() return + def refreshTree(self): + """Refresh the current tree. + """ + self.outlineTree.refreshTree(rootHandle=self.theProject.lastOutline) + return + + def clearProject(self): + self.outlineData.clearDetails() + return + + def openProjectTasks(self): + """Run opening project tasks. + """ + lastOutline = self.theProject.lastOutline + if not (lastOutline in self.theProject.tree or lastOutline is None): + lastOutline = self.theProject.tree.findRoot(nwItemClass.NOVEL) + + logger.debug("Setting outline tree to root item '%s'", lastOutline) + + self.clearProject() + self.outlineBar.populateNovelList() + self.outlineBar.setCurrentRoot(lastOutline) + + return + def closeOutline(self): self.outlineTree.closeOutline() self.outlineData.updateClasses() return - def refreshView(self, overRide=False, novelChanged=False): - self.outlineTree.refreshTree(overRide=overRide, novelChanged=novelChanged) - return + def splitSizes(self): + return self.splitOutline.sizes() def treeHasFocus(self): return self.outlineTree.hasFocus() @@ -243,6 +261,17 @@ class GuiOutlineToolBar(QToolBar): self.novelValue.addItem(tIcon, self.tr("All Novel Folders"), "") return + def setCurrentRoot(self, rootHandle): + """Set the current active root handle. + """ + if rootHandle is None: + rootIdx = self.novelValue.count() - 1 + else: + rootIdx = self.novelValue.findData(rootHandle) + if rootIdx >= 0: + self.novelValue.setCurrentIndex(rootIdx) + return + def setColumnHiddenState(self, hiddenState): """Forward the change of column hidden states to the menu. """ @@ -379,7 +408,7 @@ class GuiOutlineTree(QTreeWidget): self._lastBuild = 0 self.initOutline() - self.clearOutline() + self.clearContent() self.hiddenStateChanged.emit() @@ -415,7 +444,7 @@ class GuiOutlineTree(QTreeWidget): return - def clearOutline(self): + def clearContent(self): """Clear the tree and header and set the default values for the columns arrays. """ @@ -453,10 +482,12 @@ class GuiOutlineTree(QTreeWidget): # If the novel index or novel tree has changed since the tree # was last built, we rebuild the tree from the updated index. indexChanged = self.theProject.index.rootChangedSince(rootHandle, self._lastBuild) - doBuild = (novelChanged or indexChanged) and self.theProject.autoOutline - if doBuild or overRide: - logger.debug("Rebuilding Project Outline") - self._populateTree(rootHandle) + if not (novelChanged or indexChanged or overRide): + logger.verbose("No changes have been made to the novel index") + return + + self._populateTree(rootHandle) + self.theProject.setLastOutlineViewed(rootHandle or None) return @@ -464,7 +495,7 @@ class GuiOutlineTree(QTreeWidget): """Called before a project is closed. """ self._saveHeaderState() - self.clearOutline() + self.clearContent() self._firstView = True return diff --git a/novelwriter/gui/projtree.py b/novelwriter/gui/projtree.py index acb5e8b4..a1b5bf8e 100644 --- a/novelwriter/gui/projtree.py +++ b/novelwriter/gui/projtree.py @@ -55,7 +55,6 @@ class GuiProjectView(QWidget): # Signals triggered when the meta data values of items change treeItemChanged = pyqtSignal(str) - novelItemChanged = pyqtSignal(str) rootFolderChanged = pyqtSignal(str) wordCountsChanged = pyqtSignal() @@ -1356,8 +1355,6 @@ class GuiProjectTree(QTreeWidget): itemType = tItem.itemType if itemType == nwItemType.ROOT: self.projView.rootFolderChanged.emit(tHandle) - elif itemType == nwItemType.FILE and tItem.isNovelLike(): - self.projView.novelItemChanged.emit(tHandle) self.projView.treeItemChanged.emit(tHandle) diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py index e34b873e..6374e768 100644 --- a/novelwriter/guimain.py +++ b/novelwriter/guimain.py @@ -199,7 +199,6 @@ class GuiMain(QMainWindow): self.projView.selectedItemChanged.connect(self.itemDetails.updateViewBox) self.projView.openDocumentRequest.connect(self._openDocument) - self.projView.novelItemChanged.connect(self._treeNovelItemChanged) self.projView.wordCountsChanged.connect(self._updateStatusWordCount) self.projView.treeItemChanged.connect(self.docEditor.updateDocInfo) self.projView.treeItemChanged.connect(self.docViewer.updateDocInfo) @@ -303,7 +302,7 @@ class GuiMain(QMainWindow): self.docEditor.clearEditor() self.docEditor.setDictionaries() self.closeDocViewer() - self.outlineView.clearOutline() + self.outlineView.clearProject() # General self.statusBar.clearStatus() @@ -365,8 +364,8 @@ class GuiMain(QMainWindow): self.rebuildTrees() self.saveProject() self.docEditor.setDictionaries() - self.outlineView.updateRootItem(None) self.novelView.openProjectTasks() + self.outlineView.openProjectTasks() self.rebuildIndex(beQuiet=True) self.statusBar.setRefTime(self.theProject.projOpened) self.statusBar.setProjectStatus(nwState.GOOD) @@ -514,8 +513,8 @@ class GuiMain(QMainWindow): self.docEditor.setDictionaries() self.docEditor.toggleSpellCheck(self.theProject.spellCheck) self.statusBar.setRefTime(self.theProject.projOpened) - self.outlineView.updateRootItem(None) self.novelView.openProjectTasks() + self.outlineView.openProjectTasks() self._updateStatusWordCount() # Restore previously open documents, if any @@ -1552,18 +1551,6 @@ class GuiMain(QMainWindow): return - @pyqtSlot() - def _treeNovelItemChanged(self): - """Triggered when there is a change to a novel item in the - project tree. - """ - if self.mainStack.currentIndex() == self.idxOutlineView: - logger.verbose("Novel tree changed while Outline tab active") - if self.hasProject: - self.outlineView.refreshView(novelChanged=True) - - return - @pyqtSlot() def _keyPressReturn(self): """Forward the return/enter keypress to the function that opens @@ -1593,7 +1580,7 @@ class GuiMain(QMainWindow): elif stIndex == self.idxOutlineView: logger.verbose("Outline View activated") if self.hasProject: - self.outlineView.refreshView() + self.outlineView.refreshTree() return diff --git a/sample/nwProject.nwx b/sample/nwProject.nwx index 6ba4b5f1..b5bf2647 100644 --- a/sample/nwProject.nwx +++ b/sample/nwProject.nwx @@ -1,24 +1,23 @@ - + Sample Project Sample Project Jane Smith Jay Doh - 1371 + 1378 236 - 69222 + 69273 False en_GB True None - True 636b6aa9b697b 636b6aa9b697b 7031beac91f75 - None + 7031beac91f75 1363 954 409